~zjm/Moon3D

6c7f3e845c842c005f0fe2abeddd7e2da6fcb500 — Zack Michener a month ago bd00ebc
separate out concept of modeling
2 files changed, 87 insertions(+), 28 deletions(-)

M src/everything.h
M src/game.c
M src/everything.h => src/everything.h +23 -7
@@ 101,30 101,41 @@ typedef struct Renderer {
	ClipPlanes clip_planes;
} Renderer;

typedef struct Model {
	Vector position;
	Transform transform;
} Model;

typedef struct Renderable {
	Mesh *mesh;
	Color color;
	Model *model;
	/* lighting, materials, etc */
} Renderable;

typedef struct Physics {
	Transform position;
	Model *model;
	Vector velocity;
	Vector acceleration;
} Physics;

typedef struct SceneObject {
	Model *model;
	Renderable *renderable;
	Physics *physics;
} SceneObject;

typedef struct Particle {
	Physics physics;
	Vector position;
	Vector velocity;
	Vector acceleration;
} Particle;

typedef struct Scene {
	SceneObject *objects;
	Renderable *renderable_pool;
	Physics *physics_pool;
	Model *model_pool;
	Particle *particles;
	Renderer *renderer;
} Scene;


@@ 134,12 145,12 @@ Scene *NewScene(void);
bool LoadObj(const char *filename, Mesh *mesh);
SceneObject *CreateSceneObject(Scene *scene, const char *meshFile, Color color);
Renderable *NewRenderablePool(void);
Renderable *NewRenderable(Renderable *pool, Color color);
Renderable *NewRenderable(Renderable *pool, Model *model, Color color);
Mesh *NewMesh(void);
Physics *NewPhysicsPool(void);
Physics *NewPhysics(Physics *pool, Transform position, Vector velocity, Vector acceleration);
Physics *NewPhysics(Physics *pool, Model *model, Vector velocity, Vector acceleration);
SceneObject *NewSceneObjectPool(void);
SceneObject *NewSceneObject(SceneObject *pool, Renderable *renderable, Physics *physics);
SceneObject *NewSceneObject(SceneObject *pool, Model *model, Renderable *renderable, Physics *physics);
void InitParticleSystem(Scene *scene);
Particle *NewParticlePool(void);
Particle *AddParticle(Particle *pool, Vertex v);


@@ 151,13 162,13 @@ void UpdateScene(Scene *scene, int dt);
void UpdatePhysics(Physics physics, int dt);
void UpdateParticle(Particle particle, int dt);
void RenderScene(Scene *scene, Renderer *renderer);
void Render(Renderable renderable, Transform modelingTransform, Renderer *renderer);
void Render(Renderable renderable, Renderer *renderer);
void RenderParticle(Particle particle, Renderer *renderer);
Vertex *NewVertexPool(void);
Vertex *NewVertex(Vertex *pool);
int *NewPolygonPool(void);
void DrainRenderPools(Renderer *renderer);
void ModelVertex(Vertex *vertex, Transform t);
void ModelVertex(Vertex *vertex, Model *model);
void ProjectVertex(Vertex *vertex, Renderer *renderer);
int *ClipPolygon(int *polygon, Mesh *mesh, Renderer *renderer);
void ClipPolygonPlane(int *srcPolygon, int *dstPolygon, Mesh *mesh, Plane clipBoundary, int *polygon_pool);


@@ 178,3 189,8 @@ bool ReadObjVertex(FILE *fp, Mesh *mesh);
bool ReadObjFace(FILE *fp, Mesh *mesh);
ObjLineType ParseLineType(const char *type);
int *NewRawPool(int item_size, int max_items);
void RotateObject(SceneObject *obj, double rx, double ry, double rz);
void ScaleObject(SceneObject *obj, double sx, double sy, double sz);
void TranslateObject(SceneObject *obj, Vector dv);
void PlaceObject(SceneObject *obj, Vector p);
Model *NewModel(Model *pool);

M src/game.c => src/game.c +64 -21
@@ 84,7 84,9 @@ int main(void)
Scene *MoonWorld(void)
{
	Scene *scene = NewScene();
	CreateSceneObject(scene, "assets/moon.obj", GRAY);
	// SceneObject *moon = CreateSceneObject(scene, "assets/moon.obj", GRAY);
	// ScaleObject(moon, 10, 10, 10);
	CreateSceneObject(scene, "assets/cube.obj", BLACK);

	InitParticleSystem(scene);
	for (int i = 0; i < 1000; i++) {


@@ 106,6 108,7 @@ Scene *NewScene(void)
	scene->objects = NewPool(SceneObject, MAX_SCENE_OBJECTS);
	scene->renderable_pool = NewPool(Renderable, MAX_SCENE_OBJECTS);
	scene->physics_pool = NewPool(Physics, MAX_SCENE_OBJECTS);
	scene->model_pool = NewPool(Model, MAX_SCENE_OBJECTS);
	scene->particles = NULL;
	return scene;
}


@@ 209,28 212,29 @@ ObjLineType ParseLineType(const char *type)

SceneObject *CreateSceneObject(Scene *scene, const char *meshFile, Color color)
{
	Renderable *renderable = NewRenderable(scene->renderable_pool, color);
	Model *model = NewModel(scene->model_pool);
	Renderable *renderable = NewRenderable(scene->renderable_pool, model, color);
	LoadObj(meshFile, renderable->mesh);
	Physics *physics = NewPhysics(scene->physics_pool, Identity(), V(0, 0, 0), V(0, 0, 0));
	SceneObject *o = NewSceneObject(scene->objects, renderable, physics);
	return o;
	Physics *physics = NewPhysics(scene->physics_pool, model, V(0, 0, 0), V(0, 0, 0));
	SceneObject *obj = NewSceneObject(scene->objects, model, renderable, physics);
	return obj;
}

Renderable *NewRenderable(Renderable *pool, Color color)
Renderable *NewRenderable(Renderable *pool, Model *model, Color color)
{
	assert(PoolTotal(pool) < MAX_SCENE_OBJECTS);
	Renderable *renderable = PoolNext(pool);
	renderable->mesh = NULL;
	renderable->color = color;
	renderable->mesh = NewMesh();
	renderable->model = model;
	return renderable;
}

Physics *NewPhysics(Physics *pool, Transform position, Vector velocity, Vector acceleration)
Physics *NewPhysics(Physics *pool, Model *model, Vector velocity, Vector acceleration)
{
	assert(PoolTotal(pool) < MAX_SCENE_OBJECTS);
	Physics *physics = PoolNext(pool);
	physics->position = position;
	physics->model = model;
	physics->velocity = velocity;
	physics->acceleration = acceleration;
	return physics;


@@ 243,10 247,11 @@ int *NewRawPool(int item_size, int max_items)
	return raw_pool;
}

SceneObject *NewSceneObject(SceneObject *pool, Renderable *renderable, Physics *physics)
SceneObject *NewSceneObject(SceneObject *pool, Model *model, Renderable *renderable, Physics *physics)
{
	assert(PoolTotal(pool) < MAX_SCENE_OBJECTS);
	SceneObject *obj = PoolNext(pool);
	obj->model = model;
	obj->renderable = renderable;
	obj->physics = physics;
	return obj;


@@ 261,9 266,9 @@ Particle *AddParticle(Particle *pool, Vertex v)
{
	assert(PoolTotal(pool) < MAX_PARTICLES);
	Particle *p = PoolNext(pool);
	p->physics.position = Translation(v);
	p->physics.velocity = V(0, 0, 0);
	p->physics.acceleration = V(0, 0, 0);
	p->position = v;
	p->velocity = V(0, 0, 0);
	p->acceleration = V(0, 0, 0);
	return p;
}



@@ 363,19 368,20 @@ void UpdateScene(Scene *scene, int dt)

void UpdatePhysics(Physics physics, int dt)
{
	Translate(&physics.position, VecMul(physics.velocity, dt));
	VecAdd(physics.velocity, physics.acceleration);
	VecAdd(physics.model->position, VecMul(physics.velocity, dt));
	VecAdd(physics.velocity, VecMul(physics.acceleration, dt));
}

void UpdateParticle(Particle particle, int dt)
{
	UpdatePhysics(particle.physics, dt);
	VecAdd(particle.position, VecMul(particle.velocity, dt));
	VecAdd(particle.velocity, VecMul(particle.acceleration, dt));
}

void RenderScene(Scene *scene, Renderer *renderer)
{
	for (int i = 0; i < PoolTotal(scene->renderable_pool); i++) {
		Render(scene->renderable_pool[i], scene->physics_pool[i].position, renderer);
		Render(scene->renderable_pool[i], renderer);
	}
	for (int i = 0; i < PoolTotal(scene->particles); i++) {
		RenderParticle(scene->particles[i], renderer);


@@ 389,7 395,7 @@ void DrainRenderPools(Renderer *renderer)
	DrainPool(renderer->alt_polygon_pool);
}

void Render(Renderable renderable, Transform position, Renderer *renderer)
void Render(Renderable renderable, Renderer *renderer)
{
	int i;
	int *polygon;


@@ 424,17 430,22 @@ void Render(Renderable renderable, Transform position, Renderer *renderer)
	for (i = 0, polygon = renderMesh.faces;
		 i < PoolTotal(renderMesh.faces);
		 i++, polygon += (*polygon) + 1) {
		RasterizePolygon(polygon, renderMesh.vertices, renderer);
		// RasterizePolygon(polygon, renderMesh.vertices, renderer);
		WireframePolygon(polygon, renderMesh.vertices, renderer);
	}
}

void ModelVertex(Vertex *vertex, Transform t)
void ModelVertex(Vertex *vertex, Model *model)
{
	// TODO: optimize
	Transform t = ComposeTransform(model->transform, Translation(model->position));
	CommitTransform(t, vertex);
}

void ProjectVertex(Vertex *vertex, Renderer *renderer)
{
	// Transform camera_transform = CameraTransform(camera);
	// AddTransform(renderer->projectionTransform, &camera_transform);
	CommitTransform(renderer->projectionTransform, vertex);
}



@@ 523,7 534,7 @@ void WireframePolygon(int *polygon, Vertex *vertices, Renderer *renderer)
	previous = LastPolygonVertex(polygon, vertices);
	for (int i = 0; i < NumPolygonVertices(polygon); i++) {
		current = PolygonVertex(polygon, vertices, i);
		RasterLine(*previous, *current, WHITE, renderer);
		RasterLine(*previous, *current, BLACK, renderer);
	}
}



@@ 636,6 647,15 @@ void RenderParticle(Particle particle, Renderer *renderer)
	// TODO
}

Model *NewModel(Model *pool)
{
	assert(PoolTotal(pool) < MAX_SCENE_OBJECTS);
	Model *model = PoolNext(pool);
	model->position = V(0, 0, 0);
	model->transform = Identity();
	return model;
}

Mesh *NewMesh(void)
{
	Mesh *mesh = malloc(sizeof(Mesh));


@@ 643,3 663,26 @@ Mesh *NewMesh(void)
	mesh->faces = NewPool(int, MAX_MESH_POLYGONS);
	return mesh;
}

void RotateObject(SceneObject *obj, double rx, double ry, double rz)
{
	RotateX(&obj->model->transform, rx);
	RotateY(&obj->model->transform, ry);
	RotateZ(&obj->model->transform, rz);
}

void ScaleObject(SceneObject *obj, double sx, double sy, double sz)
{
	Scale(&obj->model->transform, sx, sy, sz);
}

void TranslateObject(SceneObject *obj, Vector dv)
{
	Translate(&obj->model->transform, dv);
}

void PlaceObject(SceneObject *obj, Vector p)
{
	obj->model->position = p;
}