-
Notifications
You must be signed in to change notification settings - Fork 74
Added core_3d_camera_fps.odin example #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi. Thanks for the PR.
There are a bunch of unnecessary type specifications that I think came along from the C code. Such as this:
hvelLength: f32 = rl.Vector3Length(hvel)
Just use hvelLength := rl.Vector3Length(hvel)
Also, there is some weird "type double dipping" happening, such as this:
desiredDir: rl.Vector3 = rl.Vector3 {
Just do
desiredDir := rl.Vector3 {
I've only given a comment once for a specific issue, but most of them happen multiple times, so please look through the file.
Also, I've set up a style guide for the examples repository. Future PRs will have it linked in the template: https://github.com/odin-lang/examples/wiki/Naming-and-style-convention
} | ||
} | ||
|
||
TOWER_SIZE: rl.Vector3 : rl.Vector3{16.0, 32.0, 16.0} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TOWER_SIZE :: rl.Vector3{16.0, 32.0, 16.0}
} | ||
} | ||
|
||
delta: f32 = rl.GetFrameTime() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use type inference delta := rl.GetFrameTime()
body.velocity.y -= GRAVITY * delta | ||
} | ||
|
||
if (body.isGrounded && jumpPressed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra parens
// Draw game level | ||
draw_level :: proc() { | ||
FLOOR_EXTENT: int : 25 | ||
TILE_SIZE: f32 : 5.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just do TILE_SIZE :: 5
. It'll implicitly cast correctly when you use it.
lookRotation.x -= mouseDelta.x * sensitivity.x | ||
lookRotation.y += mouseDelta.y * sensitivity.y | ||
|
||
sideway := i8(i8(rl.IsKeyDown(.D)) - i8(rl.IsKeyDown(.A))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both are i8
. The outer cast does nothing.
Once again, thank you Karl for all the suggestions! ❤️ The style guide is really helpful, especially for someone who writes code in multiple languages. For the Raylib examples, I originally aimed for the structure to be close to the original C examples (one-to-one), but I agree it’s more important for the Odin examples to follow the recommended naming conventions and structure. I’ll probably have some free time tomorrow to update the PR. Much appreciated! 🙏 |
Updated the code based on the feedback and the naming and style conventions guide. Used type inference where appropriate and explicitly assigned types in the remaining cases to avoid unnecessary casting. Please let me know if there are any further changes needed. Thank you Karl! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fixes. I put in a few more comments.
fovy = 60.0, | ||
projection = .PERSPECTIVE, | ||
position = rl.Vector3 { | ||
player.position.x, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird indent. Should probably be
position = player.position + {0, BOTTOM_HEIGHT + headLerp, 0}
|
||
delta := rl.GetFrameTime() | ||
headLerp = rl.Lerp(headLerp, (crouching ? CROUCH_HEIGHT : STAND_HEIGHT), 20.0 * delta) | ||
camera.position = rl.Vector3 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
camera.position = player.position + {0, BOTTOM_HEIGHT + headLerp, 0}
// Module Functions Definition | ||
//---------------------------------------------------------------------------------- | ||
// Update body considering current world state | ||
update_body :: proc(body: ^Body,rot: f32, side: i8, forward: i8, jumpPressed: bool, crouchHold: bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Body,rot
missing space
body.velocity.x = hvel.x | ||
body.velocity.z = hvel.z | ||
|
||
body.position.x += body.velocity.x * delta |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
body.position += body.velocity * delta
|
||
// Update camera for FPS behaviour | ||
update_camera_fps :: proc(camera: ^rl.Camera) { | ||
up :: rl.Vector3{0.0, 1.0, 0.0} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is a port so he camelCase
for variables is OK, since the original does that. But all your other constants use SCREAMING_SNAKE_CASE
. So this should either be a variable or be named UP
// Clamp view up | ||
maxAngleUp := rl.Vector3Angle(up, yaw) | ||
maxAngleUp -= 0.001 // Avoid numerical errors | ||
if (-(lookRotation.y) > maxAngleUp) {lookRotation.y = -maxAngleUp} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you do a single line. A few lines below you split it into several lines. Also this has unneeded parens on the condition.
draw_level :: proc() { | ||
FLOOR_EXTENT :: 25 | ||
TILE_SIZE :: 5.0 | ||
TILE_COLOR_1 := rl.Color{150, 200, 200, 255} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a constant, yet it has constant naming
TILE_COLOR_1 := rl.Color{150, 200, 200, 255} | ||
|
||
// Floor tiles | ||
for y: int = -FLOOR_EXTENT; y < FLOOR_EXTENT; y += 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could do
for y in -FLOOR_EXTENT..<FLOOR_EXTENT {
for x in -FLOOR_EXTENT..<FLOOR_EXTENT {
I understand this is a port. But anyways, if you feel like you prefer it, then change it. Always nice to show odin features etc.
rl.DrawCubeWiresV(towerPos, TOWER_SIZE, rl.DARKBLUE) | ||
|
||
// Red sun | ||
rl.DrawSphere(rl.Vector3{300.0, 300.0, 0.0}, 100, rl.Color{255, 0, 0, 255}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop the rl.Vector3
and rl.Color
: Just write
`rl.DrawSphere({300.0, 300.0, 0.0}, 100, {255, 0, 0, 255})
rl.DrawText("Camera controls:", 15, 15, 10, rl.BLACK) | ||
rl.DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, rl.BLACK) | ||
rl.DrawText("- Look around: arrow keys or mouse", 15, 45, 10, rl.BLACK) | ||
rl.DrawText(rl.TextFormat("- Velocity Len: (%06.3f)", rl.Vector2Length(rl.Vector2{player.velocity.x, player.velocity.z})), 15, 60, 10, rl.BLACK) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rl.Vector2Length(player.velocity.xz)
sensitivity := rl.Vector2{0.001, 0.001} | ||
|
||
player: Body | ||
lookRotation := rl.Vector2{0.0, 0.0} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lookRotation: rl.Vector2
|
||
player: Body | ||
lookRotation := rl.Vector2{0.0, 0.0} | ||
headTimer: f32 = 0.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
headTimer: f32
etc etc on these lines below
Thanks again for the comments! I’ll try to find some time in the next few days to make the fixes. The code was originally ported from the C example, so some C-style conventions slipped through. It’s a good practice to replace those with more Odin-oriented features, especially in a public repository. Appreciate the feedback, take care! |
Added core_3d_camera_fps.odin example which is based on raylib core_3d_camera_fps.c.
The original c example is playable here .
Checklist before submitting:
.github/workflows/check.yml
(for automatic testing)-vet -strict-style -vet-tabs -disallow-do -warnings-as-errors
core
naming convention: https://github.com/odin-lang/Odin/wiki/Naming-Convention (exception can be made for ports of examples that need to match 1:1 to the original source).