static const float smoothingThresholdAngle = TAU / 14.0f;
static const struct aiScene* importScene(const char* path);
-static Vector3D triangleNormal(Vector3D v1, Vector3D v2, Vector3D v3);
-static Vector3D convertAiVector3D(struct aiVector3D vect);
+static Vector triangleNormal(Vector v1, Vector v2, Vector v3);
+static Vector convertAiVector3D(struct aiVector3D vect);
static const char* replaceFileExtension(const struct aiString path, const char* ext);
const unsigned int numFaces = aiMesh->mNumFaces;
Mesh mesh = { .numVertices = numVertices,
- .vertices = malloc(numVertices * sizeof(Vector3D)),
+ .vertices = malloc(numVertices * sizeof(Vector)),
.normals = NULL,
.textureCoords = NULL,
.numFaces = numFaces,
}
if (aiMesh->mNormals != NULL) {
- mesh.normals = malloc(numVertices * sizeof(Vector3D));
+ mesh.normals = malloc(numVertices * sizeof(Vector));
for (unsigned int normIndex = 0; normIndex < numVertices; ++normIndex) {
mesh.normals[normIndex] = convertAiVector3D(
aiMesh->mNormals[normIndex]);
}
}
- mesh.textureCoords = malloc(numVertices * sizeof(Vector3D));
+ mesh.textureCoords = malloc(numVertices * sizeof(Vector));
for (unsigned int texcIndex = 0; texcIndex < numVertices; ++texcIndex) {
mesh.textureCoords[texcIndex] = convertAiVector3D(
aiMesh->mTextureCoords[0][texcIndex]);
Face face = { .numIndices = numIndices,
.indices = malloc(numIndices * sizeof(size_t)),
- .normals = malloc(numIndices * sizeof(Vector3D)) };
+ .normals = malloc(numIndices * sizeof(Vector)) };
for (unsigned int i = 0; i < numIndices; ++i) {
face.indices[i] = aiFace.mIndices[i];
}
if (numIndices == 3) {
- Vector3D normal = triangleNormal(mesh.vertices[face.indices[0]],
- mesh.vertices[face.indices[1]],
- mesh.vertices[face.indices[2]]);
+ Vector normal = triangleNormal(mesh.vertices[face.indices[0]],
+ mesh.vertices[face.indices[1]],
+ mesh.vertices[face.indices[2]]);
for (size_t i = 0; i < numIndices; ++i) {
face.normals[i] = normal;
}
Face face = mesh.faces[faceIndex];
if (face.normals) {
- face.normals = memcpy(malloc(face.numIndices * sizeof(Vector3D)),
+ face.normals = memcpy(malloc(face.numIndices * sizeof(Vector)),
face.normals,
- face.numIndices * sizeof(Vector3D));
+ face.numIndices * sizeof(Vector));
for (size_t indexIndex = 0; indexIndex < face.numIndices; ++indexIndex) {
- Vector3D smoothedNormal = face.normals[indexIndex];
+ Vector smoothedNormal = face.normals[indexIndex];
for (size_t i = 0; i < mesh.numFaces; ++i) {
if (i == faceIndex || !mesh.faces[i].normals) {
return scene;
}
-static Vector3D triangleNormal(Vector3D v1, Vector3D v2, Vector3D v3) {
+static Vector triangleNormal(Vector v1, Vector v2, Vector v3) {
return normalized(crossProduct(subtractVectors(v2, v1), subtractVectors(v3, v1)));
}
-static Vector3D convertAiVector3D(struct aiVector3D vect) {
- return (Vector3D) { .x = vect.x,
- .y = vect.y,
- .z = vect.z };
+static Vector convertAiVector3D(struct aiVector3D vect) {
+ return (Vector) { .x = vect.x,
+ .y = vect.y,
+ .z = vect.z };
}
/**
struct Mesh {
size_t numVertices;
- Vector3D* vertices;
- Vector3D* normals;
- Vector3D* textureCoords;
+ Vector* vertices;
+ Vector* normals;
+ Vector* textureCoords;
size_t numFaces;
Face* faces;
size_t materialIndex;
struct Face {
size_t numIndices;
size_t* indices;
- Vector3D* normals;
+ Vector* normals;
};
struct Material {
return result;
}
-void translate(Transform* transform, Vector3D vec) {
+void translate(Transform* transform, Vector vec) {
*transform = multiply(
(Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = vec.x,
.b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = vec.y,
*transform);
}
-void rotate(Transform* transform, Vector3D axis, float angle) {
+void rotate(Transform* transform, Vector axis, float angle) {
axis = normalized(axis);
float l = axis.x;
float m = axis.y;
*transform);
}
-Vector3D addVectors(Vector3D v1, Vector3D v2){
- return (Vector3D) { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
+Vector addVectors(Vector v1, Vector v2){
+ return (Vector) { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
}
-Vector3D subtractVectors(Vector3D v1, Vector3D v2) {
- return (Vector3D) { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
+Vector subtractVectors(Vector v1, Vector v2) {
+ return (Vector) { v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
}
-Vector3D crossProduct(Vector3D v1, Vector3D v2) {
- return (Vector3D) { .x = (v1.y * v2.z) - (v1.z * v2.y),
- .y = (v1.z * v2.x) - (v1.x * v2.z),
- .z = (v1.x * v2.y) - (v1.y * v2.x) };
+Vector crossProduct(Vector v1, Vector v2) {
+ return (Vector) { .x = (v1.y * v2.z) - (v1.z * v2.y),
+ .y = (v1.z * v2.x) - (v1.x * v2.z),
+ .z = (v1.x * v2.y) - (v1.y * v2.x) };
}
-float dotProduct(Vector3D v1, Vector3D v2) {
+float dotProduct(Vector v1, Vector v2) {
return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
}
-Vector3D scaleVector(Vector3D vec, float scale) {
- return (Vector3D) { vec.x * scale,
- vec.y * scale,
- vec.z * scale };
+Vector scaleVector(Vector vec, float scale) {
+ return (Vector) { vec.x * scale,
+ vec.y * scale,
+ vec.z * scale };
}
-Vector3D clampMagnitude(Vector3D vec, float maxMagnitude) {
+Vector clampMagnitude(Vector vec, float maxMagnitude) {
float m = magnitude(vec);
if (m > maxMagnitude) {
vec = scaleVector(vec, maxMagnitude / m);
return vec;
}
-float magnitude(Vector3D vec) {
+float magnitude(Vector vec) {
return sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
}
-Vector3D applyTransform(Transform transform, Vector3D vec) {
+Vector applyTransform(Transform transform, Vector vec) {
GLfloat* a = (GLfloat*) &transform;
GLfloat b[4] = { vec.x, vec.y, vec.z, 1.0f };
GLfloat c[4];
+ a[(row * 4) + 2] * b[2]
+ a[(row * 4) + 3] * b[3];
}
- return (Vector3D) { c[0], c[1], c[2] };
+ return (Vector) { c[0], c[1], c[2] };
}
-Vector3D translationOf(Transform transform) {
- return (Vector3D) { transform.a4, transform.b4, transform.c4 };
+Vector translationOf(Transform transform) {
+ return (Vector) { transform.a4, transform.b4, transform.c4 };
}
-Vector3D normalized(Vector3D vec) {
+Vector normalized(Vector vec) {
float m = magnitude(vec);
- return (Vector3D) { vec.x / m, vec.y / m, vec.z / m };
+ return (Vector) { vec.x / m, vec.y / m, vec.z / m };
}
#include <GL/gl.h>
-typedef struct Vector3D Vector3D;
+typedef struct Vector Vector;
typedef struct Transform Transform;
-struct Vector3D {
+struct Vector {
float x;
float y;
float z;
Transform identity();
Transform multiply(Transform t1, Transform t2);
-void translate(Transform* transform, Vector3D vec);
-void rotate(Transform* transform, Vector3D axis, float angle);
-Vector3D addVectors(Vector3D v1, Vector3D v2);
-Vector3D subtractVectors(Vector3D v1, Vector3D v2);
-Vector3D crossProduct(Vector3D v1, Vector3D v2);
-float dotProduct(Vector3D v1, Vector3D v2);
-Vector3D scaleVector(Vector3D vec, float scale);
-Vector3D clampMagnitude(Vector3D vec, float maxMagnitude);
-float magnitude(Vector3D vec);
-Vector3D applyTransform(Transform transform, Vector3D vec);
-Vector3D translationOf(Transform transform);
-Vector3D normalized(Vector3D vec);
+void translate(Transform* transform, Vector vec);
+void rotate(Transform* transform, Vector axis, float angle);
+Vector addVectors(Vector v1, Vector v2);
+Vector subtractVectors(Vector v1, Vector v2);
+Vector crossProduct(Vector v1, Vector v2);
+float dotProduct(Vector v1, Vector v2);
+Vector scaleVector(Vector vec, float scale);
+Vector clampMagnitude(Vector vec, float maxMagnitude);
+float magnitude(Vector vec);
+Vector applyTransform(Transform transform, Vector vec);
+Vector translationOf(Transform transform);
+Vector normalized(Vector vec);
#endif // ENGINE_GEOMETRY_H_
static void moveCameraTo(const Scene* anchor) {
glMatrixMode(GL_PROJECTION);
- Vector3D pos = translationOf(worldTransform(anchor));
+ Vector pos = translationOf(worldTransform(anchor));
glTranslatef(-pos.x, -pos.y, -pos.z);
}
glBegin(GL_LINES);
for (size_t i = 0; i < face.numIndices; ++i) {
size_t vertIndex = face.indices[i];
- Vector3D vertex = mesh.vertices[vertIndex];
- Vector3D normal = face.normals[i];
+ Vector vertex = mesh.vertices[vertIndex];
+ Vector normal = face.normals[i];
glColor3f(absolute(normal.x), absolute(normal.y), absolute(normal.z));
glVertex3f(vertex.x, vertex.y, vertex.z);
glVertex3f(vertex.x + normal.x, vertex.y + normal.y, vertex.z + normal.z);
size_t vertIndex = face.indices[i];
if (face.normals) {
if (mesh.textureCoords) {
- Vector3D coords = mesh.textureCoords[vertIndex];
+ Vector coords = mesh.textureCoords[vertIndex];
glTexCoord2f(coords.x, coords.y);
}
- Vector3D normal = face.normals[i];
+ Vector normal = face.normals[i];
glNormal3f(normal.x, normal.y, normal.z);
}
- Vector3D vertex = mesh.vertices[vertIndex];
+ Vector vertex = mesh.vertices[vertIndex];
glVertex3f(vertex.x, vertex.y, vertex.z);
}
void initLevel() {
playerSpawnTransform = identity();
- translate(&playerSpawnTransform, (Vector3D) { .x = -BLOCKGRID_CELL_SIZE,
- .y = 0.0f,
- .z = -BLOCKGRID_CELL_SIZE });
+ translate(&playerSpawnTransform, (Vector) { .x = -BLOCKGRID_CELL_SIZE,
+ .y = 0.0f,
+ .z = -BLOCKGRID_CELL_SIZE });
blockWall01.solid = importSolid("assets/wall01.3ds");
for (size_t z = 0; z < levelGrid.depth; ++z) {
for (size_t x = 0; x < levelGrid.width; ++x) {
Scene* blockScene = newScene();
- translate(&blockScene->transform, (Vector3D) { .x = x * BLOCKGRID_CELL_SIZE,
- .y = 0.0f,
- .z = z * BLOCKGRID_CELL_SIZE });
+ translate(&blockScene->transform, (Vector) { .x = x * BLOCKGRID_CELL_SIZE,
+ .y = 0.0f,
+ .z = z * BLOCKGRID_CELL_SIZE });
blockScene->solid = getBlockFromGrid(levelGrid, x, z)->solid;
insertChildScene(levelScene, blockScene);
}
case 0xFF00FFFF:
block = &blockEmpty;
playerSpawnTransform = identity();
- translate(&playerSpawnTransform, (Vector3D) { .x = x * BLOCKGRID_CELL_SIZE,
- .y = 0.0f,
- .z = z * BLOCKGRID_CELL_SIZE });
+ translate(&playerSpawnTransform, (Vector) { .x = x * BLOCKGRID_CELL_SIZE,
+ .y = 0.0f,
+ .z = z * BLOCKGRID_CELL_SIZE });
break;
default:
block = &blockEmpty;
Scene* playerCharacter;
static Transform screenToWorldMovementTransform;
-static Vector3D worldMovementUp;
-static Vector3D worldMovementDown;
-static Vector3D worldMovementLeft;
-static Vector3D worldMovementRight;
+static Vector worldMovementUp;
+static Vector worldMovementDown;
+static Vector worldMovementLeft;
+static Vector worldMovementRight;
static Direction movementDirection;
-static void movePlayer(Vector3D direction, float delta);
-static Vector3D worldMovementDirection(float x, float y);
+static void movePlayer(Vector direction, float delta);
+static Vector worldMovementDirection(float x, float y);
void initPlayer() {
screenToWorldMovementTransform = identity();
- rotate(&screenToWorldMovementTransform, (Vector3D) { 0.0f, 1.0f, 0.0f }, - TAU / 8.0f);
+ rotate(&screenToWorldMovementTransform, (Vector) { 0.0f, 1.0f, 0.0f }, - TAU / 8.0f);
worldMovementUp = worldMovementDirection(0.0f, 1.0f);
worldMovementDown = worldMovementDirection(0.0f, -1.0f);
}
void updatePlayer(float delta) {
- Vector3D direction = { 0.0f, 0.0f, 0.0f };
+ Vector direction = { 0.0f, 0.0f, 0.0f };
if (movementDirection & DIRECTION_UP) {
direction = addVectors(direction, worldMovementUp);
}
movementDirection &= ~direction;
}
-static void movePlayer(Vector3D direction, float delta) {
+static void movePlayer(Vector direction, float delta) {
direction = clampMagnitude(direction, 1.0f);
- Vector3D displacement = scaleVector(direction, delta * movementSpeed);
+ Vector displacement = scaleVector(direction, delta * movementSpeed);
translate(&playerCharacter->transform, displacement);
}
-static Vector3D worldMovementDirection(float x, float y) {
- Vector3D direction = (Vector3D) { x, 0.0f, -y };
+static Vector worldMovementDirection(float x, float y) {
+ Vector direction = (Vector) { x, 0.0f, -y };
direction = normalized(
applyTransform(screenToWorldMovementTransform, direction));
return direction;