Refactor spatial, add documentation

This commit is contained in:
Dane Johnson
2021-01-26 23:28:20 -06:00
parent b242b7b0e2
commit fbd2d7d61b
9 changed files with 293 additions and 73 deletions

View File

@@ -1,11 +1,35 @@
/**
@file
@author Dane Johnson <dane@danejohnson.org>
@section LICENSE
Couch Copyright (C) 2021 Dane Johnson
This program comes with ABSOLUTELY NO WARRANTY; without event the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for details at
https://www.gnu.org/licenses/gpl-3.0.html
This is free software, and you are welcome to redistribute it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
@section DESCRIPTION
This file defines the cameras that can be used to render the scene
*/
#ifndef CAMERA_H
#define CAMERA_H
#include "Transform.h"
#include "Spatial.h"
class Camera {
/**
The common 3D camera
*/
class Camera : public Spatial {
public:
Transform transform;
Camera();
void MakeCurrent();
static Camera *GetCurrentCamera();

View File

@@ -1,8 +1,7 @@
/**
@file
@author Dane Johnson <dane@danejohnson.org>
/*
Dane Johnson <dane@danejohnson.org>
@section LICENSE
LICENSE
Couch Copyright (C) 2021 Dane Johnson
@@ -16,7 +15,7 @@
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
@section DESCRIPTION
DESCRIPTION
Node is the parent class for all classes that would be in the scene
tree. The root of the scene tree is always a node.

View File

@@ -56,23 +56,26 @@ RigidbodyMotionState::RigidbodyMotionState(Rigidbody *rigidbody) {
}
void RigidbodyMotionState::getWorldTransform(btTransform &worldTrans) const {
Transform transform = rigidbody->GetTransform();
worldTrans.setOrigin(btVector3(
rigidbody->transform.position.x,
rigidbody->transform.position.y,
rigidbody->transform.position.z));
transform.position.x,
transform.position.y,
transform.position.z));
btQuaternion quat;
quat.setEuler(rigidbody->transform.rotation.z,
rigidbody->transform.rotation.y,
rigidbody->transform.rotation.x);
quat.setEuler(transform.rotation.z,
transform.rotation.y,
transform.rotation.x);
worldTrans.setRotation(quat);
}
void RigidbodyMotionState::setWorldTransform(const btTransform &worldTrans) {
rigidbody->transform.position = Vector3(worldTrans.getOrigin().getX(),
Transform transform = rigidbody->GetTransform();
transform.position = Vector3(worldTrans.getOrigin().getX(),
worldTrans.getOrigin().getY(),
worldTrans.getOrigin().getZ());
worldTrans.getRotation().getEulerZYX(rigidbody->transform.rotation.z,
rigidbody->transform.rotation.y,
rigidbody->transform.rotation.x);
worldTrans.getRotation().getEulerZYX(transform.rotation.z,
transform.rotation.y,
transform.rotation.x);
rigidbody->SetTransform(transform);
}

View File

@@ -1,11 +1,71 @@
/*
Dane Johnson <dane@danejohnson.org>
LICENSE
Couch Copyright (C) 2021 Dane Johnson
This program comes with ABSOLUTELY NO WARRANTY; without event the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for details at
https://www.gnu.org/licenses/gpl-3.0.html
This is free software, and you are welcome to redistribute it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
DESCRIPTION
A spatial is a node with a transform property, i.e. position, scale or rotation.
They can be instanced on the scene tree as an anchor for some other nodes.
*/
#include "Spatial.h"
Name Spatial::GetType() const {return "Spatial";}
Transform Spatial::GetTransform() {
return transform;
}
void Spatial::SetTransform(Transform transform) {
this->transform = transform;
}
Spatial *Spatial::Create() {
return new Spatial;
}
void Spatial::Translate(Vector3 offset) {
Transform t = this->GetTransform();
t.position += offset;
this->SetTransform(t);
}
void Spatial::RotateX(cfloat phi) {
Transform t = this->GetTransform();
t.rotation.x += phi;
this->SetTransform(t);
}
void Spatial::RotateY(cfloat phi) {
Transform t = this->GetTransform();
t.rotation.y += phi;
this->SetTransform(t);
}
void Spatial::RotateZ(cfloat phi) {
Transform t = this->GetTransform();
t.rotation.z += phi;
this->SetTransform(t);
}
void Spatial::UniformScale(cfloat scale) {
Transform t = this->GetTransform();
t.scale *= scale;
this->SetTransform(t);
}
Spatial *Spatial::Duplicate() {
Spatial *spatial = static_cast<Spatial*>(Node::Duplicate());
spatial->transform = transform;

View File

@@ -1,17 +1,83 @@
/**
@file
@author Dane Johnson <dane@danejohnson.org>
@section LICENSE
Couch Copyright (C) 2021 Dane Johnson
This program comes with ABSOLUTELY NO WARRANTY; without event the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for details at
https://www.gnu.org/licenses/gpl-3.0.html
This is free software, and you are welcome to redistribute it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
@section DESCRIPTION
A spatial is a node with a transform property, i.e. position, scale or rotation.
They can be instanced on the scene tree as an anchor for some other nodes.
*/
#ifndef SPATIAL_H
#define SPATIAL_H
#include "types.h"
#include "Node.h"
#include "Transform.h"
/**
Spatial nodes have a transform property. They can be subclassed or instanced
as an anchor for their children.
*/
class Spatial : public Node {
public:
Transform transform;
virtual bool IsTransformable() const { return true;}
virtual Name GetType() const;
/**
Gets the transform property of this spatial
@return The transform
*/
Transform GetTransform();
/**
Sets the transform property of this spatial.
@param transform The transform property
*/
void SetTransform(Transform transform);
/**
Directly translates the spatial by offset
@param offset The offset of the transform operation
*/
void Translate(Vector3 offset);
/**
Rotates the Camera phi radians about the X axis
@param phi The amount to rotate in radians
*/
void RotateX(cfloat phi);
/**
Rotates the Camera phi radians about the Y axis
@param phi The amount to rotate in radians
*/
void RotateY(cfloat phi);
/**
Rotates the Camera phi radians about the Z axis
@param phi The amount to rotate in radians
*/
void RotateZ(cfloat phi);
/**
Scales the spatial by scale uniformly
@param scale The amount to scale by.
*/
void UniformScale(cfloat scale);
virtual Spatial *Create();
virtual Spatial *Duplicate();
virtual Spatial *Instance();
private:
Transform transform;
};
#endif /* SPATIAL_H */

View File

@@ -1,4 +1,26 @@
/*
Dane Johnson <dane@danejohnson.org>
LICENSE
Couch Copyright (C) 2021 Dane Johnson
This program comes with ABSOLUTELY NO WARRANTY; without event the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for details at
https://www.gnu.org/licenses/gpl-3.0.html
This is free software, and you are welcome to redistribute it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
DESCRIPTION
A transform represents various aspects of 3d space.
*/
#include "Transform.h"
#include <glm/gtc/matrix_transform.hpp>
Transform::Transform() {
position = Vector3(0.0f);
@@ -19,21 +41,6 @@ Transform::Transform(Vector3 position, Vector3 rotation, Vector3 scale) {
}
void Transform::Translate(cfloat x, cfloat y, cfloat z) {
position = position + Vector3(x, y, z);
}
Matrix Transform::RotationMatrix() {
Matrix mat(1.0f);
mat = glm::rotate(mat, this->rotation.z, Vector3(0.0f, 0.0f, 1.0f));
mat = glm::rotate(mat, this->rotation.y, Vector3(0.0f, 1.0f, 0.0f));
mat = glm::rotate(mat, this->rotation.x, Vector3(1.0f, 0.0f, 0.0f));
return mat;
}
Vector3 Transform::Forward() {
return glm::vec3(RotationMatrix() * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f));
}
@@ -45,3 +52,13 @@ Vector3 Transform::Up() {
Vector3 Transform::Right() {
return glm::vec3(RotationMatrix() * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
}
Matrix Transform::RotationMatrix() {
Matrix mat(1.0f);
mat = glm::rotate(mat, this->rotation.z, Vector3(0.0f, 0.0f, 1.0f));
mat = glm::rotate(mat, this->rotation.y, Vector3(0.0f, 1.0f, 0.0f));
mat = glm::rotate(mat, this->rotation.x, Vector3(1.0f, 0.0f, 0.0f));
return mat;
}

View File

@@ -1,21 +1,65 @@
/**
@file
@author Dane Johnson <dane@danejohnson.org>
@section LICENSE
Couch Copyright (C) 2021 Dane Johnson
This program comes with ABSOLUTELY NO WARRANTY; without event the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for details at
https://www.gnu.org/licenses/gpl-3.0.html
This is free software, and you are welcome to redistribute it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
@section DESCRIPTION
A transform represents various aspects of 3d space.
*/
#ifndef TRANSFORM_H
#define TRANSFORM_H
#include <glm/gtc/matrix_transform.hpp>
#include "types.h"
/**
A Transform represents a position, rotation, and scale in 3D space.
*/
struct Transform {
Transform();
Transform(Vector3 position, Vector3 rotation);
Transform(Vector3 position, Vector3 rotation, Vector3 scale);
/**
The position, according to the left-hand rule
*/
Vector3 position;
/**
The rotation, in Euler angles
*/
Vector3 rotation;
/**
Scaling along the specified axis
*/
Vector3 scale;
void Translate(cfloat x, cfloat y, cfloat z);
/**
Returns a vector that is -Z, rotated by @ref rotation.
*/
Vector3 Forward();
/**
Returns a vector that is +X, rotated by @ref rotation.
*/
Vector3 Right();
/**
Returns a vector that is +Y, rotated by @ref rotation.
*/
Vector3 Up();
/**
Returns a matrix that, when multiplied by a @ref Vector3
gives a Vector rotated by @ref rotation
*/
Matrix RotationMatrix();
};

View File

@@ -43,11 +43,12 @@ Node *root;
void render(Node *curr, Shader *shader, Matrix model) {
Spatial *spatial = dynamic_cast<Spatial*>(curr);
if (spatial) {
model = glm::rotate(model, spatial->transform.rotation.x, Vector3(1.0f, 0.0f, 0.0f));
model = glm::rotate(model, spatial->transform.rotation.y, Vector3(0.0f, 1.0f, 0.0f));
model = glm::rotate(model, spatial->transform.rotation.z, Vector3(0.0f, 0.0f, 1.0f));
model = glm::translate(model, spatial->transform.position);
model = glm::scale(model, spatial->transform.scale);
Transform transform = spatial->GetTransform();
model = glm::rotate(model, transform.rotation.x, Vector3(1.0f, 0.0f, 0.0f));
model = glm::rotate(model, transform.rotation.y, Vector3(0.0f, 1.0f, 0.0f));
model = glm::rotate(model, transform.rotation.z, Vector3(0.0f, 0.0f, 1.0f));
model = glm::translate(model, transform.position);
model = glm::scale(model, transform.scale);
shader->UpdateModel(model);
shader->UpdateNormal(glm::mat3(glm::transpose(glm::inverse(model))));
}
@@ -126,10 +127,11 @@ int main() {
shader->UpdateProjection(projection);
Matrix view(1.0f);
Camera *camera = Camera::GetCurrentCamera();
view = glm::rotate(view, -camera->transform.rotation.x, Vector3(1.0f, 0.0f, 0.0f));
view = glm::rotate(view, -camera->transform.rotation.y, Vector3(0.0f, 1.0f, 0.0f));
view = glm::rotate(view, -camera->transform.rotation.z, Vector3(0.0f, 0.0f, 1.0f));
view = glm::translate(view, -camera->transform.position);
Transform camera_transform = camera->GetTransform();
view = glm::rotate(view, -camera_transform.rotation.x, Vector3(1.0f, 0.0f, 0.0f));
view = glm::rotate(view, -camera_transform.rotation.y, Vector3(0.0f, 1.0f, 0.0f));
view = glm::rotate(view, -camera_transform.rotation.z, Vector3(0.0f, 0.0f, 1.0f));
view = glm::translate(view, -camera_transform.position);
shader->UpdateView(view);
// Find the lights