Skip to content

Commit 463575e

Browse files
committed
Refactor, add Car component and example parented cube
1 parent 43a94ce commit 463575e

File tree

2 files changed

+74
-60
lines changed

2 files changed

+74
-60
lines changed

src/scenes/nfs.cpp

Lines changed: 72 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "nfs.hpp"
2+
#include "components/parent.hpp"
3+
#include "render/model/3d/cube.hpp"
24
#include "render/model/3d/sphere.hpp"
35

46
#include <expected>
@@ -130,6 +132,19 @@ static std::expected<void, std::string> startup(/* clang-format off */
130132

131133
registry->emplace<components::Velocity>(ent, glm::vec3(0.0f, 0.0f, 0.0f));
132134
registry->emplace<components::AngularVelocity>(ent, glm::vec3(0.0f, 0.0f, 0.0f));
135+
registry->emplace<scenes::nfs::components::Car>(ent); // mark as car entity
136+
137+
auto cubeModel = std::make_shared<model::Cube>(glm::vec3(1.0f));
138+
139+
auto cubeEnt = registry->create();
140+
registry->emplace<components::Position>(cubeEnt, -constants::WORLD_FORWARD * 5.0f);
141+
registry->emplace<components::Child>(cubeEnt, ent); // make it a child of the car
142+
registry->emplace<components::Model3D>(cubeEnt, cubeModel);
143+
144+
std::vector<entt::entity> carChildren;
145+
carChildren.push_back(cubeEnt);
146+
147+
registry->emplace<components::Parent>(ent, carChildren); // make car a parent of the cube
133148
}
134149

135150
{ // city
@@ -178,8 +193,8 @@ static std::expected<void, std::string> update(/* clang-format off */
178193
) { /* clang-format on */
179194

180195
// Car controller system
181-
auto carView =
182-
registry->view<components::Position, components::Rotation, components::Velocity, components::AngularVelocity>();
196+
auto carView = registry->view<components::Position, components::Rotation, components::Velocity, components::AngularVelocity,
197+
scenes::nfs::components::Car>();
183198

184199
for (auto entity : carView) {
185200
auto& position = carView.get<components::Position>(entity);
@@ -268,81 +283,78 @@ static std::expected<void, std::string> update(/* clang-format off */
268283
angularVelocity.value.z = targetAngularVelocity;
269284
}
270285

271-
// GTA 5-style camera system
272-
auto carView = registry->view<components::Position, components::Rotation>();
273-
for (auto carEntity : carView) {
274-
auto& carPosition = carView.get<components::Position>(carEntity);
275-
auto& carRotation = carView.get<components::Rotation>(carEntity);
286+
// GTA 5-style camera system - use the current car entity
287+
auto& carPosition = position; // Use the current car's position
288+
auto& carRotation = rotation; // Use the current car's rotation
276289

277-
// Get car forward direction
278-
glm::vec3 carForward = carRotation.value * glm::vec3(0.0f, 1.0f, 0.0f);
290+
// Get car forward direction
291+
glm::vec3 carForward = carRotation.value * glm::vec3(0.0f, 1.0f, 0.0f);
279292

280-
// Handle mouse input for camera rotation
281-
glm::vec2 mouseDelta = input::Mouse::getPositionDelta();
282-
bool hasMouseInput = glm::length(mouseDelta) > 0.01f;
293+
// Handle mouse input for camera rotation
294+
glm::vec2 mouseDelta = input::Mouse::getPositionDelta();
295+
bool hasMouseInput = glm::length(mouseDelta) > 0.01f;
283296

284-
if (hasMouseInput) {
285-
// Apply mouse sensitivity with delta time for frame-rate independent movement
286-
float deltaTimeSensitivity = cameraState->mouseSensitivity * time.deltaTime;
287-
cameraState->yaw -= mouseDelta.x * deltaTimeSensitivity;
288-
cameraState->pitch += mouseDelta.y * deltaTimeSensitivity; // Fixed inversion
297+
if (hasMouseInput) {
298+
// Apply mouse sensitivity with delta time for frame-rate independent movement
299+
float deltaTimeSensitivity = cameraState->mouseSensitivity * time.deltaTime;
300+
cameraState->yaw -= mouseDelta.x * deltaTimeSensitivity;
301+
cameraState->pitch += mouseDelta.y * deltaTimeSensitivity; // Fixed inversion
289302

290-
// Clamp pitch to prevent camera flipping
291-
cameraState->pitch = std::clamp(cameraState->pitch, -1.4f, 0.5f); // About -80° to +30°
303+
// Clamp pitch to prevent camera flipping
304+
cameraState->pitch = std::clamp(cameraState->pitch, -1.4f, 0.5f); // About -80° to +30°
292305

293-
cameraState->isUserControlling = true;
294-
cameraState->timeSinceLastInput = 0.0f;
295-
} else {
296-
cameraState->timeSinceLastInput += time.deltaTime;
306+
cameraState->isUserControlling = true;
307+
cameraState->timeSinceLastInput = 0.0f;
308+
} else {
309+
cameraState->timeSinceLastInput += time.deltaTime;
297310

298-
// Start auto-centering after delay
299-
if (cameraState->timeSinceLastInput > cameraState->autoReturnDelay) {
300-
cameraState->isUserControlling = false;
311+
// Start auto-centering after delay
312+
if (cameraState->timeSinceLastInput > cameraState->autoReturnDelay) {
313+
cameraState->isUserControlling = false;
301314

302-
// Calculate target yaw (behind the car)
303-
glm::vec3 carForwardXY = glm::normalize(glm::vec3(carForward.x, carForward.y, 0.0f));
304-
cameraState->targetYaw = atan2(carForwardXY.y, carForwardXY.x) + constants::PI; // Behind the car
315+
// Calculate target yaw (behind the car)
316+
glm::vec3 carForwardXY = glm::normalize(glm::vec3(carForward.x, carForward.y, 0.0f));
317+
cameraState->targetYaw = atan2(carForwardXY.y, carForwardXY.x) + constants::PI; // Behind the car
305318

306-
// Smoothly interpolate back to target position
307-
float returnSpeed = cameraState->autoReturnSpeed * time.deltaTime;
319+
// Smoothly interpolate back to target position
320+
float returnSpeed = cameraState->autoReturnSpeed * time.deltaTime;
308321

309-
// Handle yaw wrapping (shortest rotation path)
310-
float yawDiff = cameraState->targetYaw - cameraState->yaw;
311-
while (yawDiff > glm::pi<float>())
312-
yawDiff -= 2.0f * glm::pi<float>();
313-
while (yawDiff < -glm::pi<float>())
314-
yawDiff += 2.0f * glm::pi<float>();
322+
// Handle yaw wrapping (shortest rotation path)
323+
float yawDiff = cameraState->targetYaw - cameraState->yaw;
324+
while (yawDiff > glm::pi<float>())
325+
yawDiff -= 2.0f * glm::pi<float>();
326+
while (yawDiff < -glm::pi<float>())
327+
yawDiff += 2.0f * glm::pi<float>();
315328

316-
cameraState->yaw += yawDiff * returnSpeed;
317-
cameraState->pitch += (cameraState->targetPitch - cameraState->pitch) * returnSpeed;
318-
}
329+
cameraState->yaw += yawDiff * returnSpeed;
330+
cameraState->pitch += (cameraState->targetPitch - cameraState->pitch) * returnSpeed;
319331
}
332+
}
320333

321-
// Calculate camera position based on yaw, pitch, and distance
322-
float cosYaw = cos(cameraState->yaw);
323-
float sinYaw = sin(cameraState->yaw);
324-
float cosPitch = cos(cameraState->pitch);
325-
float sinPitch = sin(cameraState->pitch);
334+
// Calculate camera position based on yaw, pitch, and distance
335+
float cosYaw = cos(cameraState->yaw);
336+
float sinYaw = sin(cameraState->yaw);
337+
float cosPitch = cos(cameraState->pitch);
338+
float sinPitch = sin(cameraState->pitch);
326339

327-
// Camera offset in spherical coordinates (negative distance to position behind car)
328-
glm::vec3 cameraOffset;
329-
cameraOffset.x = -cameraState->distance * cosYaw * cosPitch;
330-
cameraOffset.y = -cameraState->distance * sinYaw * cosPitch;
331-
cameraOffset.z = cameraState->height + cameraState->distance * sinPitch;
340+
// Camera offset in spherical coordinates (negative distance to position behind car)
341+
glm::vec3 cameraOffset;
342+
cameraOffset.x = -cameraState->distance * cosYaw * cosPitch;
343+
cameraOffset.y = -cameraState->distance * sinYaw * cosPitch;
344+
cameraOffset.z = cameraState->height + cameraState->distance * sinPitch;
332345

333-
glm::vec3 cameraPos = carPosition.value + cameraOffset;
346+
glm::vec3 cameraPos = carPosition.value + cameraOffset;
334347

335-
// Camera looks at the car (with slight forward offset)
336-
glm::vec3 lookTarget = carPosition.value + carForward * 1.0f + glm::vec3(0.0f, 0.0f, 1.0f);
337-
glm::vec3 cameraDir = glm::normalize(lookTarget - cameraPos);
348+
// Camera looks at the car (with slight forward offset)
349+
glm::vec3 lookTarget = carPosition.value + carForward * 1.0f + glm::vec3(0.0f, 0.0f, 1.0f);
350+
glm::vec3 cameraDir = glm::normalize(lookTarget - cameraPos);
338351

339-
// Update renderer camera
340-
renderer->setCameraPos(cameraPos);
341-
renderer->setCameraDir(cameraDir);
352+
// Update renderer camera
353+
renderer->setCameraPos(cameraPos);
354+
renderer->setCameraDir(cameraDir);
342355

343-
// Only handle the first car entity for now
344-
break;
345-
}
356+
// Only handle the first car entity for now
357+
break;
346358
}
347359

348360
return {};

src/scenes/nfs.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ class Game;
55

66
namespace scenes::nfs {
77
namespace components {
8+
struct Car {};
9+
810
struct CameraState {
911
float yaw = 0.0f; // Horizontal rotation around the car
1012
float pitch = -0.1f; // Vertical angle (looking down slightly at the car)

0 commit comments

Comments
 (0)