mirror of
https://github.com/HandmadeMath/HandmadeMath.git
synced 2025-09-10 12:18:16 +00:00
WIP camera stuff. Missing some useful quaternion helpers.
This commit is contained in:
@@ -23,7 +23,40 @@ public:
|
|||||||
|
|
||||||
RenderComponent *renderComponent = NULL;
|
RenderComponent *renderComponent = NULL;
|
||||||
|
|
||||||
|
struct CameraInfo {
|
||||||
|
float fov = 90.0f;
|
||||||
|
float aspect = 1024.0f / 768.0f;
|
||||||
|
float near = 0.1f;
|
||||||
|
float far = 100.0f;
|
||||||
|
};
|
||||||
|
CameraInfo camera;
|
||||||
|
|
||||||
|
hmm_mat4 projectionMatrix() {
|
||||||
|
return HMM_Perspective(camera.fov, camera.aspect, camera.near, camera.far);
|
||||||
|
}
|
||||||
|
|
||||||
|
hmm_mat4 viewMatrix() {
|
||||||
|
return HMM_LookAt(worldPosition(), worldPosition() + forward(), up());
|
||||||
|
}
|
||||||
|
|
||||||
|
hmm_vec3 worldPosition() {
|
||||||
|
return (modelMatrix * HMM_Vec4(0.0f, 0.0f, 0.0f, 1.0f)).XYZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
hmm_vec3 up() {
|
||||||
|
return (modelMatrix * HMM_Vec4(0.0f, 1.0f, 0.0f, 1.0f)).XYZ - worldPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
hmm_vec3 forward() {
|
||||||
|
return (modelMatrix * HMM_Vec4(1.0f, 0.0f, 0.0f, 1.0f)).XYZ - worldPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
hmm_vec3 right() {
|
||||||
|
return (modelMatrix * HMM_Vec4(0.0f, 0.0f, 1.0f, 1.0f)).XYZ - worldPosition();
|
||||||
|
}
|
||||||
|
|
||||||
// Context for rendering and stuff
|
// Context for rendering and stuff
|
||||||
|
hmm_mat4 parentModelMatrix;
|
||||||
hmm_mat4 modelMatrix;
|
hmm_mat4 modelMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
58
example/src/FollowCam.h
Normal file
58
example/src/FollowCam.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef HMME_FOLLOWCAM_H
|
||||||
|
#define HMME_FOLLOWCAM_H
|
||||||
|
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "HandmadeMath.h"
|
||||||
|
|
||||||
|
class FollowCam : public Entity {
|
||||||
|
public:
|
||||||
|
Entity *target;
|
||||||
|
|
||||||
|
FollowCam(Entity *t) {
|
||||||
|
target = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HI BEN HERE IS YOUR STREAM OF CONSCIOUSNESS
|
||||||
|
//
|
||||||
|
// Up is wonky. Really this whole thing is a little wonky, although it's
|
||||||
|
// gotten pretty close. You need to figure out how to directly calculate the
|
||||||
|
// axis and angle so you don't have to do this in two steps. Then it should
|
||||||
|
// Just Work.
|
||||||
|
//
|
||||||
|
// Although you may have to figure out how to make the camera keep a consistent up vector.
|
||||||
|
//
|
||||||
|
// Actually that shouldn't be too hard, because once you have a quaternion
|
||||||
|
// LookAt thing, you can just always pass world up to it.
|
||||||
|
|
||||||
|
void Tick(float deltaSeconds) override {
|
||||||
|
// rotation = HMM_QuaternionFromAxisAngle(target->worldPosition() - worldPosition(), 0.0f);
|
||||||
|
// rotation = HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 1.0f, 0.0f), HMM_ToRadians(0.0f));
|
||||||
|
// rotation = HMM_Qu
|
||||||
|
|
||||||
|
hmm_vec3 fwd = (parentModelMatrix * HMM_Vec4(1.0f, 0.0f, 0.0f, 0.0f)).XYZ;
|
||||||
|
hmm_vec3 up = (parentModelMatrix * HMM_Vec4(0.0f, 1.0f, 0.0f, 0.0f)).XYZ;
|
||||||
|
hmm_vec3 to = target->worldPosition() - worldPosition();
|
||||||
|
float dot = HMM_DotVec3(fwd, HMM_NormalizeVec3(to));
|
||||||
|
|
||||||
|
if (HMM_ABS(dot - 1.0f) < 0.000001f) {
|
||||||
|
// do nothing to the rotation
|
||||||
|
} else if (HMM_ABS(dot + 1.0f) < 0.000001f) {
|
||||||
|
// rotate 180 I guess but for now do nothing
|
||||||
|
} else {
|
||||||
|
hmm_vec3 cross = HMM_Normalize(HMM_Cross(fwd, to));
|
||||||
|
|
||||||
|
rotation = HMM_QuaternionFromAxisAngle(
|
||||||
|
cross,
|
||||||
|
HMM_ACOSF(dot)
|
||||||
|
);
|
||||||
|
rotation *= HMM_QuaternionFromAxisAngle(
|
||||||
|
HMM_Vec3(1.0f, 0.0f, 0.0f),
|
||||||
|
-HMM_ACOSF(HMM_DotVec3(cross, up))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@@ -11,6 +11,7 @@
|
|||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
#include "Cube.h"
|
#include "Cube.h"
|
||||||
#include "MeshRenderComponent.h"
|
#include "MeshRenderComponent.h"
|
||||||
|
#include "FollowCam.h"
|
||||||
|
|
||||||
void TickTree(Entity *e, float deltaSeconds);
|
void TickTree(Entity *e, float deltaSeconds);
|
||||||
void ComputeModelMatrices(Entity *ep, hmm_mat4 parentModelMatrix);
|
void ComputeModelMatrices(Entity *ep, hmm_mat4 parentModelMatrix);
|
||||||
@@ -67,17 +68,27 @@ int main()
|
|||||||
// Accept fragment if it closer to the camera than the former one
|
// Accept fragment if it closer to the camera than the former one
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
|
|
||||||
Cube root = Cube();
|
Cube c1 = Cube();
|
||||||
|
|
||||||
Entity child = Entity();
|
Entity monkey = Entity();
|
||||||
child.position = HMM_Vec3(2.1f, 0.0f, 0.0f);
|
monkey.position = HMM_Vec3(2.1f, 0.0f, 0.0f);
|
||||||
child.renderComponent = new MeshRenderComponent("MonkeySmooth.obj");
|
monkey.renderComponent = new MeshRenderComponent("MonkeySmooth.obj");
|
||||||
|
|
||||||
|
FollowCam cam = FollowCam(&monkey);
|
||||||
|
// cam.position = HMM_Vec3(3.0f, 3.0f, 4.0f);
|
||||||
|
cam.position = HMM_Vec3(3.0f, 3.0f, 5.0f);
|
||||||
|
// cam.rotation = HMM_QuaternionFromAxisAngle(HMM_Vec3(0.0f, 1.0f, 0.0f), HMM_ToRadians(90.0f));
|
||||||
|
|
||||||
// Cube c = Cube();
|
// Cube c = Cube();
|
||||||
// child.position = HMM_Vec3(2.1f, 0.0f, 0.0f);
|
// monkey.position = HMM_Vec3(2.1f, 0.0f, 0.0f);
|
||||||
|
|
||||||
// child.AddChild(&c);
|
// monkey.AddChild(&c);
|
||||||
root.AddChild(&child);
|
|
||||||
|
c1.AddChild(&monkey);
|
||||||
|
|
||||||
|
Entity root = Entity();
|
||||||
|
root.AddChild(&c1);
|
||||||
|
root.AddChild(&cam);
|
||||||
|
|
||||||
bool hasTicked = false;
|
bool hasTicked = false;
|
||||||
high_resolution_clock::time_point lastTickTime;
|
high_resolution_clock::time_point lastTickTime;
|
||||||
@@ -85,10 +96,6 @@ int main()
|
|||||||
do {
|
do {
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
hmm_mat4 projection = HMM_Perspective(90.0f, 1024.0f / 768.0f, 0.1f, 100.0f);
|
|
||||||
hmm_mat4 view = HMM_LookAt(HMM_Vec3(3.0f, 3.0f, 4.0f), HMM_Vec3(0.0f, 0.0f, 0.0f), HMM_Vec3(0.0f, 1.0f, 0.0f));
|
|
||||||
hmm_mat4 vp = projection * view;
|
|
||||||
|
|
||||||
// Tick
|
// Tick
|
||||||
auto now = high_resolution_clock::now();
|
auto now = high_resolution_clock::now();
|
||||||
if (hasTicked) {
|
if (hasTicked) {
|
||||||
@@ -103,6 +110,10 @@ int main()
|
|||||||
ComputeModelMatrices(&root, HMM_Mat4d(1.0f));
|
ComputeModelMatrices(&root, HMM_Mat4d(1.0f));
|
||||||
|
|
||||||
// Render!
|
// Render!
|
||||||
|
hmm_mat4 projection = cam.projectionMatrix();
|
||||||
|
hmm_mat4 view = cam.viewMatrix();
|
||||||
|
hmm_mat4 vp = projection * view;
|
||||||
|
|
||||||
auto it = EntityIterator(&root);
|
auto it = EntityIterator(&root);
|
||||||
while (it.HasNext()) {
|
while (it.HasNext()) {
|
||||||
Entity *e = it.Next();
|
Entity *e = it.Next();
|
||||||
@@ -142,6 +153,7 @@ void TickTree(Entity *e, float deltaSeconds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ComputeModelMatrices(Entity *e, hmm_mat4 parentModelMatrix) {
|
void ComputeModelMatrices(Entity *e, hmm_mat4 parentModelMatrix) {
|
||||||
|
e->parentModelMatrix = parentModelMatrix;
|
||||||
e->modelMatrix = parentModelMatrix * HMM_Translate(e->position) * HMM_QuaternionToMat4(e->rotation) * HMM_Scale(e->scale);
|
e->modelMatrix = parentModelMatrix * HMM_Translate(e->position) * HMM_QuaternionToMat4(e->rotation) * HMM_Scale(e->scale);
|
||||||
|
|
||||||
for (int i = 0; i < e->children.size(); i++) {
|
for (int i = 0; i < e->children.size(); i++) {
|
||||||
|
Reference in New Issue
Block a user