Fix entity origin and rotation about origin
Fundamental mismatch between rotation and offset of polygons. Polygons can be arbitrarily ordered in terms of vertices as long as they are in a CCW order. However there should be no restriction on the starting vertex position. Since this is the case, the entity offset for a polygon should offset from the starting vertex to the perceived "entity origin". This entity origin is where collision detection, rotation and movement is based off.
This commit is contained in:
		
							parent
							
								
									01f99dd0ca
								
							
						
					
					
						commit
						20749dd668
					
				
							
								
								
									
										124
									
								
								src/Asteroid.c
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								src/Asteroid.c
									
									
									
									
									
								
							| @ -177,8 +177,11 @@ v2 *createAsteroidVertexList(MemoryArena_ *arena, i32 iterations, | |||||||
| 	for (i32 i = 0; i < iterations; i++) | 	for (i32 i = 0; i < iterations; i++) | ||||||
| 	{ | 	{ | ||||||
| 		i32 randValue = rand(); | 		i32 randValue = rand(); | ||||||
| 		result[i] = V2(math_cosf(iterationAngle * i) * asteroidRadius, | 		 | ||||||
| 		               math_sinf(iterationAngle * i) * asteroidRadius); | 		// NOTE(doyle): Sin/cos generate values from +-1, we want to create
 | ||||||
|  | 		// vertices that start from 0, 0 (i.e. strictly positive)
 | ||||||
|  | 		result[i] = V2(((math_cosf(iterationAngle * i) + 1) * asteroidRadius), | ||||||
|  | 		               ((math_sinf(iterationAngle * i) + 1) * asteroidRadius)); | ||||||
| 
 | 
 | ||||||
| #if 1 | #if 1 | ||||||
| 		f32 displacementDist   = 0.50f * asteroidRadius; | 		f32 displacementDist   = 0.50f * asteroidRadius; | ||||||
| @ -239,6 +242,27 @@ v2 *createEntityEdgeList(MemoryArena_ *transientArena, Entity *entity) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | v2 calculateProjectionRangeForEdge(Entity *entity, v2 edgeNormal) | ||||||
|  | { | ||||||
|  | 	v2 result = {0}; | ||||||
|  | 	result.max = v2_dot(entity->vertexPoints[0], edgeNormal); | ||||||
|  | 	result.max = result.min; | ||||||
|  | 
 | ||||||
|  | 	for (i32 vertexIndex = 0; vertexIndex < entity->numVertexPoints; | ||||||
|  | 	     vertexIndex++) | ||||||
|  | 	{ | ||||||
|  | 		f32 dist = | ||||||
|  | 		    v2_dot(entity->vertexPoints[vertexIndex], edgeNormal); | ||||||
|  | 
 | ||||||
|  | 		if (dist < result.min) | ||||||
|  | 			result.min = dist; | ||||||
|  | 		else if (dist > result.max) | ||||||
|  | 			result.max = dist; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| b32 checkEntityProjectionOverlap(Entity *entity, Entity *checkEntity, | b32 checkEntityProjectionOverlap(Entity *entity, Entity *checkEntity, | ||||||
|                                  v2 *entityEdges) |                                  v2 *entityEdges) | ||||||
| { | { | ||||||
| @ -246,39 +270,10 @@ b32 checkEntityProjectionOverlap(Entity *entity, Entity *checkEntity, | |||||||
| 	for (i32 edgeIndex = 0; edgeIndex < entity->numVertexPoints && result; | 	for (i32 edgeIndex = 0; edgeIndex < entity->numVertexPoints && result; | ||||||
| 	     edgeIndex++) | 	     edgeIndex++) | ||||||
| 	{ | 	{ | ||||||
| 		v2 entityProjectionRange = {0}; | 		v2 entityProjectionRange = | ||||||
| 		entityProjectionRange.max = | 		    calculateProjectionRangeForEdge(entity, entityEdges[edgeIndex]); | ||||||
| 		    v2_dot(entity->vertexPoints[0], entityEdges[0]); | 		v2 checkEntityProjectionRange = calculateProjectionRangeForEdge( | ||||||
| 		entityProjectionRange.max = entityProjectionRange.min; | 		    checkEntity, entityEdges[edgeIndex]); | ||||||
| 
 |  | ||||||
| 		for (i32 vertexIndex = 0; vertexIndex < entity->numVertexPoints; |  | ||||||
| 		     vertexIndex++) |  | ||||||
| 		{ |  | ||||||
| 			f32 dist = v2_dot(entity->vertexPoints[vertexIndex], |  | ||||||
| 			                  entityEdges[edgeIndex]); |  | ||||||
| 
 |  | ||||||
| 			if (dist < entityProjectionRange.min) |  | ||||||
| 				entityProjectionRange.min = dist; |  | ||||||
| 			else if (dist > entityProjectionRange.max) |  | ||||||
| 				entityProjectionRange.max = dist; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		v2 checkEntityProjectionRange = {0}; |  | ||||||
| 		checkEntityProjectionRange.min = |  | ||||||
| 		    v2_dot(entity->vertexPoints[0], entityEdges[0]); |  | ||||||
| 		checkEntityProjectionRange.max = checkEntityProjectionRange.min; |  | ||||||
| 
 |  | ||||||
| 		for (i32 vertexIndex = 0; vertexIndex < checkEntity->numVertexPoints; |  | ||||||
| 		     vertexIndex++) |  | ||||||
| 		{ |  | ||||||
| 			f32 dist = v2_dot(checkEntity->vertexPoints[vertexIndex], |  | ||||||
| 			                  entityEdges[edgeIndex]); |  | ||||||
| 
 |  | ||||||
| 			if (dist < checkEntityProjectionRange.min) |  | ||||||
| 				checkEntityProjectionRange.min = dist; |  | ||||||
| 			else if (dist > checkEntityProjectionRange.max) |  | ||||||
| 				checkEntityProjectionRange.max = dist; |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		if (!v2_intervalsOverlap(entityProjectionRange, | 		if (!v2_intervalsOverlap(entityProjectionRange, | ||||||
| 		                         checkEntityProjectionRange)) | 		                         checkEntityProjectionRange)) | ||||||
| @ -337,13 +332,15 @@ void moveEntity(GameState *state, Entity *entity, v2 ddP, f32 dt, f32 ddPSpeed) | |||||||
| 				// Convert inplace the vector normal of the edges
 | 				// Convert inplace the vector normal of the edges
 | ||||||
| 				for (i32 i = 0; i < numEntityEdges; i++) | 				for (i32 i = 0; i < numEntityEdges; i++) | ||||||
| 				{ | 				{ | ||||||
| 					entityEdges[i] = V2(entityEdges[i].y, -entityEdges[i].x); | 					entityEdges[i] = v2_perpendicular(entityEdges[i]); | ||||||
|  | 					entityEdges[i] = v2_add(entityEdges[i], entity->pos); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				for (i32 i = 0; i < numCheckEntityEdges; i++) | 				for (i32 i = 0; i < numCheckEntityEdges; i++) | ||||||
| 				{ | 				{ | ||||||
|  | 					checkEntityEdges[i] = v2_perpendicular(checkEntityEdges[i]); | ||||||
| 					checkEntityEdges[i] = | 					checkEntityEdges[i] = | ||||||
| 					    V2(entityEdges[i].y, -entityEdges[i].x); | 					    v2_add(checkEntityEdges[i], checkEntity->pos); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if ((checkEntityProjectionOverlap(entity, checkEntity, | 				if ((checkEntityProjectionOverlap(entity, checkEntity, | ||||||
| @ -355,7 +352,9 @@ void moveEntity(GameState *state, Entity *entity, v2 ddP, f32 dt, f32 ddPSpeed) | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (willCollide) break; | 			if (willCollide) { | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
| @ -397,15 +396,13 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 			ship->vertexPoints    = memory_pushBytes( | 			ship->vertexPoints    = memory_pushBytes( | ||||||
| 			    &state->persistentArena, sizeof(v2) * ship->numVertexPoints); | 			    &state->persistentArena, sizeof(v2) * ship->numVertexPoints); | ||||||
| 
 | 
 | ||||||
| 			Basis shipBasis     = getDefaultBasis(ship); | 			v2 triangleBaseP  = V2(0, 0); | ||||||
| 			v2 triangleTopPoint = V2(shipBasis.pos.x + (ship->size.w * 0.5f), | 			v2 triangleTopP   = V2(ship->size.w * 0.5f, ship->size.h); | ||||||
| 			                         shipBasis.pos.y + ship->size.h); | 			v2 triangleRightP = V2(ship->size.w, triangleBaseP.y); | ||||||
| 			v2 triangleRightSide = |  | ||||||
| 			    V2(shipBasis.pos.x + ship->size.w, shipBasis.pos.y); |  | ||||||
| 
 | 
 | ||||||
| 			ship->vertexPoints[0] = shipBasis.pos; | 			ship->vertexPoints[0] = triangleBaseP; | ||||||
| 			ship->vertexPoints[1] = triangleRightSide; | 			ship->vertexPoints[1] = triangleRightP; | ||||||
| 			ship->vertexPoints[2] = triangleTopPoint; | 			ship->vertexPoints[2] = triangleTopP; | ||||||
| 
 | 
 | ||||||
| 			ship->scale      = 1; | 			ship->scale      = 1; | ||||||
| 			ship->type       = entitytype_ship; | 			ship->type       = entitytype_ship; | ||||||
| @ -414,7 +411,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 			ship->tex        = NULL; | 			ship->tex        = NULL; | ||||||
| 			ship->collides   = TRUE; | 			ship->collides   = TRUE; | ||||||
| 
 | 
 | ||||||
| 			i32 numAsteroids = 10; | 			i32 numAsteroids = 8; | ||||||
| 			for (i32 i = 0; i < numAsteroids; i++) | 			for (i32 i = 0; i < numAsteroids; i++) | ||||||
| 			{ | 			{ | ||||||
| 				Entity *asteroid = &state->entityList[state->entityIndex]; | 				Entity *asteroid = &state->entityList[state->entityIndex]; | ||||||
| @ -427,13 +424,13 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 
 | 
 | ||||||
| 				asteroid->size       = V2(100.0f, 100.0f); | 				asteroid->size       = V2(100.0f, 100.0f); | ||||||
| 				asteroid->hitbox     = asteroid->size; | 				asteroid->hitbox     = asteroid->size; | ||||||
| 				asteroid->offset     = v2_scale(asteroid->size, 0.5f); | 				asteroid->offset     = V2(asteroid->size.w * -0.5f, 0); | ||||||
| 				asteroid->scale      = 1; | 				asteroid->scale      = 1; | ||||||
| 				asteroid->type       = entitytype_asteroid; | 				asteroid->type       = entitytype_asteroid; | ||||||
| 				asteroid->direction  = direction_null; | 				asteroid->direction  = direction_null; | ||||||
| 				asteroid->renderMode = rendermode_polygon; | 				asteroid->renderMode = rendermode_polygon; | ||||||
| 
 | 
 | ||||||
| 				asteroid->numVertexPoints = 16; | 				asteroid->numVertexPoints = 8; | ||||||
| 				asteroid->vertexPoints    = createAsteroidVertexList( | 				asteroid->vertexPoints    = createAsteroidVertexList( | ||||||
| 				    &state->persistentArena, asteroid->numVertexPoints, | 				    &state->persistentArena, asteroid->numVertexPoints, | ||||||
| 				    (i32)(asteroid->size.x * 0.5f)); | 				    (i32)(asteroid->size.x * 0.5f)); | ||||||
| @ -535,8 +532,6 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			ddPSpeedInMs = 25; | 			ddPSpeedInMs = 25; | ||||||
| 			pivotPoint = v2_scale(entity->size, 0.5f); |  | ||||||
| 
 |  | ||||||
| 			DEBUG_PUSH_VAR("Pos: %5.2f, %5.2f", entity->pos, "v2"); | 			DEBUG_PUSH_VAR("Pos: %5.2f, %5.2f", entity->pos, "v2"); | ||||||
| 			DEBUG_PUSH_VAR("Velocity: %5.2f, %5.2f", entity->dP, "v2"); | 			DEBUG_PUSH_VAR("Velocity: %5.2f, %5.2f", entity->dP, "v2"); | ||||||
| 			DEBUG_PUSH_VAR("Rotation: %5.2f", entity->rotation, "f32"); | 			DEBUG_PUSH_VAR("Rotation: %5.2f", entity->rotation, "f32"); | ||||||
| @ -617,39 +612,20 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 
 | 
 | ||||||
| 			// NOTE(doyle): Make asteroids start and move at constant speed
 | 			// NOTE(doyle): Make asteroids start and move at constant speed
 | ||||||
| 			ddPSpeedInMs = 2; | 			ddPSpeedInMs = 2; | ||||||
| 			entity->dP = v2_scale(ddP, state->pixelsPerMeter * ddPSpeedInMs); | 			entity->dP   = v2_scale(ddP, state->pixelsPerMeter * ddPSpeedInMs); | ||||||
|  | 			entity->rotation += (randValue % 20) * dt; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		moveEntity(state, entity, ddP, dt, ddPSpeedInMs); | 		moveEntity(state, entity, ddP, dt, ddPSpeedInMs); | ||||||
| 
 | 
 | ||||||
| 		RenderFlags flags = renderflag_wireframe | renderflag_no_texture; | 		RenderFlags flags = renderflag_wireframe | renderflag_no_texture; | ||||||
| 		renderer_entity(&state->renderer, &state->transientArena, state->camera, | 		renderer_entity(&state->renderer, &state->transientArena, state->camera, | ||||||
| 		                entity, pivotPoint, 0, V4(0.4f, 0.8f, 1.0f, 1.0f), | 		                entity, V2(0, 0), 0, | ||||||
| 		                flags); | 		                V4(0.4f, 0.8f, 1.0f, 1.0f), flags); | ||||||
| 
 |  | ||||||
| 		Basis entityBasis = getDefaultBasis(entity); |  | ||||||
| 		renderer_rect(&state->renderer, state->camera, entityBasis.pos, |  | ||||||
| 		              V2(4, 4), entityBasis.pivotPoint, |  | ||||||
| 		              DEGREES_TO_RADIANS(entity->rotation), NULL, |  | ||||||
| 		              V4(1.0f, 0, 0, 1.0f), flags); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| #if 1 |  | ||||||
| 	TrianglePoints triangle = {0}; |  | ||||||
| 	triangle.points[0] = V2(100, 200); |  | ||||||
| 	triangle.points[1] = V2(200, 100); |  | ||||||
| 	triangle.points[2] = V2(100, 300); |  | ||||||
| 
 |  | ||||||
| 	LOCAL_PERSIST Degrees rotation = 0.0f; |  | ||||||
| 	rotation += (60.0f) * dt; |  | ||||||
| 
 |  | ||||||
| 	RenderFlags flags = renderflag_wireframe | renderflag_no_texture; |  | ||||||
| 	renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0), |  | ||||||
| 	                  rotation, NULL, V4(1, 1, 1, 1), flags); |  | ||||||
| 
 |  | ||||||
| 	debug_drawUi(state, dt); | 	debug_drawUi(state, dt); | ||||||
| 	debug_clearCounter(); | 	debug_clearCounter(); | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 	renderer_renderGroups(&state->renderer); | 	renderer_renderGroups(&state->renderer); | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										50
									
								
								src/Entity.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/Entity.c
									
									
									
									
									
								
							| @ -86,53 +86,3 @@ void entity_addAnim(AssetManager *const assetManager, Entity *const entity, | |||||||
| 
 | 
 | ||||||
| 	DEBUG_LOG("No more free entity animation slots"); | 	DEBUG_LOG("No more free entity animation slots"); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| Basis getBasis(Entity *entity, enum RectBaseline baseline) |  | ||||||
| { |  | ||||||
| 	ASSERT(baseline < rectbaseline_count); |  | ||||||
| 
 |  | ||||||
| 	v2 basis = v2_sub(entity->pos, entity->offset); |  | ||||||
| 	v2 pivotPoint = v2_scale(entity->size, 0.5f); |  | ||||||
| 	v2 size = entity->size; |  | ||||||
| 	switch (baseline) |  | ||||||
| 	{ |  | ||||||
| 		case rectbaseline_top: |  | ||||||
| 			basis.y += (size.h); |  | ||||||
| 			basis.x += (size.w * 0.5f); |  | ||||||
| 		    break; |  | ||||||
| 		case rectbaseline_topLeft: |  | ||||||
| 			basis.y += (size.h); |  | ||||||
| 		    break; |  | ||||||
| 		case rectbaseline_topRight: |  | ||||||
| 		    basis.y += (size.h); |  | ||||||
| 		    basis.x += (size.w); |  | ||||||
| 		    break; |  | ||||||
| 		case rectbaseline_bottom: |  | ||||||
| 			basis.x += (size.w * 0.5f); |  | ||||||
| 			break; |  | ||||||
| 		case rectbaseline_bottomRight: |  | ||||||
| 			basis.x += (size.w); |  | ||||||
| 			break; |  | ||||||
| 		case rectbaseline_left: |  | ||||||
| 			basis.y += (size.h * 0.5f); |  | ||||||
| 			break; |  | ||||||
| 		case rectbaseline_right: |  | ||||||
| 			basis.x += (size.w); |  | ||||||
| 			basis.y += (size.h * 0.5f); |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case rectbaseline_bottomLeft: |  | ||||||
| 		    break; |  | ||||||
| 		default: |  | ||||||
| 		    DEBUG_LOG( |  | ||||||
| 		        "getPosRelativeToRect() warning: baseline enum not recognised"); |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Basis result      = {0}; |  | ||||||
| 	result.pos        = basis; |  | ||||||
| 	result.pivotPoint = pivotPoint; |  | ||||||
| 
 |  | ||||||
| 	return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -13,11 +13,6 @@ typedef struct RenderQuad | |||||||
| 	Vertex vertex[4]; | 	Vertex vertex[4]; | ||||||
| } RenderQuad_; | } RenderQuad_; | ||||||
| 
 | 
 | ||||||
| typedef struct RenderTriangle |  | ||||||
| { |  | ||||||
| 	Vertex vertex[3]; |  | ||||||
| } RenderTriangle_; |  | ||||||
| 
 |  | ||||||
| // NOTE(doyle): A vertex batch is the batch of vertexes comprised to make one
 | // NOTE(doyle): A vertex batch is the batch of vertexes comprised to make one
 | ||||||
| // shape
 | // shape
 | ||||||
| INTERNAL void beginVertexBatch(Renderer *renderer) | INTERNAL void beginVertexBatch(Renderer *renderer) | ||||||
| @ -317,30 +312,6 @@ INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer, |  | ||||||
|                                               TrianglePoints triangle, |  | ||||||
|                                               v2 pivotPoint, Radians rotate, |  | ||||||
|                                               RenderTex renderTex) |  | ||||||
| { |  | ||||||
| 	/* Convert texture coordinates to normalised texture coordinates */ |  | ||||||
| 	v4 texRectNdc = getTexRectNormaliseDeviceCoords(renderTex); |  | ||||||
| 
 |  | ||||||
| 	RenderTriangle_ result = {0}; |  | ||||||
| 	result.vertex[0].pos       = triangle.points[0]; |  | ||||||
| 	result.vertex[0].texCoord  = V2(texRectNdc.x, texRectNdc.w); |  | ||||||
| 
 |  | ||||||
| 	result.vertex[1].pos       = triangle.points[1]; |  | ||||||
| 	result.vertex[1].texCoord  = V2(texRectNdc.x, texRectNdc.y); |  | ||||||
| 
 |  | ||||||
| 	result.vertex[2].pos       = triangle.points[2]; |  | ||||||
| 	result.vertex[2].texCoord  = V2(texRectNdc.z, texRectNdc.w); |  | ||||||
| 
 |  | ||||||
| 	applyRotationToVertexes(triangle.points[0], pivotPoint, rotate, |  | ||||||
| 	                        result.vertex, ARRAY_COUNT(result.vertex)); |  | ||||||
| 
 |  | ||||||
| 	return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| INTERNAL inline RenderQuad_ | INTERNAL inline RenderQuad_ | ||||||
| createDefaultTexQuad(Renderer *renderer, RenderTex *renderTex) | createDefaultTexQuad(Renderer *renderer, RenderTex *renderTex) | ||||||
| { | { | ||||||
| @ -447,31 +418,21 @@ void renderer_polygon(Renderer *const renderer, Rect camera, | |||||||
| 	{ | 	{ | ||||||
| 		ASSERT((i + 1) < numPoints); | 		ASSERT((i + 1) < numPoints); | ||||||
| 
 | 
 | ||||||
| 		RenderTriangle_ tri = {0}; | 		Vertex triangle[3] = {0}; | ||||||
| 		tri.vertex[0].pos  = triangulationBaseP; | 		triangle[0].pos    = triangulationBaseP; | ||||||
| 		tri.vertex[1].pos  = polygonPoints[i]; | 		triangle[1].pos    = polygonPoints[i]; | ||||||
| 		tri.vertex[2].pos  = polygonPoints[i + 1]; | 		triangle[2].pos    = polygonPoints[i + 1]; | ||||||
| 
 | 
 | ||||||
| 		applyRotationToVertexes(triangulationBaseP, pivotPoint, rotate, | 		applyRotationToVertexes(triangulationBaseP, pivotPoint, rotate, | ||||||
| 		                        tri.vertex, 3); | 		                        triangle, ARRAY_COUNT(triangle)); | ||||||
| 		addVertexToRenderGroup_(renderer, renderTex->tex, color, tri.vertex, | 		addVertexToRenderGroup_(renderer, renderTex->tex, color, triangle, | ||||||
| 		                        ARRAY_COUNT(tri.vertex), rendermode_polygon, | 		                        ARRAY_COUNT(triangle), rendermode_polygon, | ||||||
| 		                        flags); | 		                        flags); | ||||||
| 		triangulationIndex++; | 		triangulationIndex++; | ||||||
| 	} | 	} | ||||||
| 	endVertexBatch(renderer); | 	endVertexBatch(renderer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void renderer_triangle(Renderer *const renderer, Rect camera, |  | ||||||
|                        TrianglePoints triangle, v2 pivotPoint, Degrees rotate, |  | ||||||
|                        RenderTex *renderTex, v4 color, RenderFlags flags) |  | ||||||
| { |  | ||||||
| 	Radians totalRotation = DEGREES_TO_RADIANS(rotate); |  | ||||||
| 	renderer_polygon(renderer, camera, triangle.points, |  | ||||||
| 	                 ARRAY_COUNT(triangle.points), pivotPoint, totalRotation, |  | ||||||
| 	                 renderTex, color, flags); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | ||||||
|                      Font *const font, const char *const string, v2 pos, |                      Font *const font, const char *const string, v2 pos, | ||||||
|                      v2 pivotPoint, Radians rotate, v4 color, RenderFlags flags) |                      v2 pivotPoint, Radians rotate, v4 color, RenderFlags flags) | ||||||
| @ -573,21 +534,6 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, | |||||||
| 		renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint, | 		renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint, | ||||||
| 		              totalRotation, &renderTex, color, flags); | 		              totalRotation, &renderTex, color, flags); | ||||||
| 	} | 	} | ||||||
| 	else if (entity->renderMode == rendermode_triangle) |  | ||||||
| 	{ |  | ||||||
| 		Basis entityBasis   = getDefaultBasis(entity); |  | ||||||
| 		v2 triangleTopPoint = V2(entityBasis.pos.x + (entity->size.w * 0.5f), |  | ||||||
| 		                         entityBasis.pos.y + entity->size.h); |  | ||||||
| 		v2 triangleRightSide = |  | ||||||
| 		    V2(entityBasis.pos.x + entity->size.w, entityBasis.pos.y); |  | ||||||
| 
 |  | ||||||
| 		v2 entityPolygonPoints[] = {entityBasis.pos, triangleRightSide, |  | ||||||
| 		                            triangleTopPoint}; |  | ||||||
| 
 |  | ||||||
| 		renderer_polygon(renderer, camera, entityPolygonPoints, |  | ||||||
| 		                 ARRAY_COUNT(entityPolygonPoints), pivotPoint, |  | ||||||
| 		                 totalRotation, &renderTex, color, flags); |  | ||||||
| 	} |  | ||||||
| 	else if (entity->renderMode == rendermode_polygon) | 	else if (entity->renderMode == rendermode_polygon) | ||||||
| 	{ | 	{ | ||||||
| 		ASSERT(entity->numVertexPoints >= 3); | 		ASSERT(entity->numVertexPoints >= 3); | ||||||
| @ -595,14 +541,17 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, | |||||||
| 
 | 
 | ||||||
| 		v2 *offsetVertexPoints = memory_pushBytes( | 		v2 *offsetVertexPoints = memory_pushBytes( | ||||||
| 		    transientArena, entity->numVertexPoints * sizeof(v2)); | 		    transientArena, entity->numVertexPoints * sizeof(v2)); | ||||||
|  | 
 | ||||||
| 		for (i32 i = 0; i < entity->numVertexPoints; i++) | 		for (i32 i = 0; i < entity->numVertexPoints; i++) | ||||||
| 		{ | 		{ | ||||||
| 			offsetVertexPoints[i] = | 			offsetVertexPoints[i] = | ||||||
| 			    v2_add(entity->vertexPoints[i], entity->pos); | 			    v2_add(entity->vertexPoints[i], entity->offset); | ||||||
|  | 			offsetVertexPoints[i] = v2_add(offsetVertexPoints[i], entity->pos); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		renderer_polygon(renderer, camera, offsetVertexPoints, | 		renderer_polygon(renderer, camera, offsetVertexPoints, | ||||||
| 		                 entity->numVertexPoints, pivotPoint, totalRotation, | 		                 entity->numVertexPoints, | ||||||
|  | 		                 v2_add(entity->offset, pivotPoint), totalRotation, | ||||||
| 		                 &renderTex, color, flags); | 		                 &renderTex, color, flags); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
|  | |||||||
| @ -22,27 +22,6 @@ enum Direction | |||||||
| 	direction_num, | 	direction_num, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef struct Basis |  | ||||||
| { |  | ||||||
| 	v2 pos; |  | ||||||
| 	v2 pivotPoint; |  | ||||||
| } Basis; |  | ||||||
| 
 |  | ||||||
| enum RectBaseline |  | ||||||
| { |  | ||||||
| 	rectbaseline_top, |  | ||||||
| 	rectbaseline_topLeft, |  | ||||||
| 	rectbaseline_topRight, |  | ||||||
| 	rectbaseline_bottom, |  | ||||||
| 	rectbaseline_bottomRight, |  | ||||||
| 	rectbaseline_bottomLeft, |  | ||||||
| 	rectbaseline_left, |  | ||||||
| 	rectbaseline_right, |  | ||||||
| 	rectbaseline_center, |  | ||||||
| 	rectbaseline_count, |  | ||||||
| 
 |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| enum EntityType | enum EntityType | ||||||
| { | { | ||||||
| 	entitytype_invalid, | 	entitytype_invalid, | ||||||
| @ -72,6 +51,12 @@ typedef struct Entity | |||||||
| 
 | 
 | ||||||
| 	v2 hitbox; | 	v2 hitbox; | ||||||
| 	v2 size; | 	v2 size; | ||||||
|  | 
 | ||||||
|  | 	// NOTE(doyle): Offset from origin point to the entity's considered "center"
 | ||||||
|  | 	// point, all operations work from this point, i.e. rotation, movement,
 | ||||||
|  | 	// collision detection
 | ||||||
|  | 	// If this is a polygon, the offset should be from the 1st vertex point
 | ||||||
|  | 	// specified
 | ||||||
| 	v2 offset; | 	v2 offset; | ||||||
| 
 | 
 | ||||||
| 	enum RenderMode renderMode; | 	enum RenderMode renderMode; | ||||||
| @ -110,13 +95,4 @@ void entity_setActiveAnim(Entity *const entity, const char *const animName); | |||||||
| void entity_updateAnim(Entity *const entity, const f32 dt); | void entity_updateAnim(Entity *const entity, const f32 dt); | ||||||
| void entity_addAnim(AssetManager *const assetManager, Entity *const entity, | void entity_addAnim(AssetManager *const assetManager, Entity *const entity, | ||||||
|                     const char *const animName); |                     const char *const animName); | ||||||
| 
 |  | ||||||
| Basis getBasis(Entity *entity, enum RectBaseline baseline); |  | ||||||
| inline Basis getDefaultBasis(Entity *entity) |  | ||||||
| { |  | ||||||
| 	Basis result = getBasis(entity, rectbaseline_bottomLeft); |  | ||||||
| 	return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -203,6 +203,11 @@ INTERNAL inline b32 v2_intervalsOverlap(const v2 a, const v2 b) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | INTERNAL inline v2 v2_perpendicular(const v2 a) { | ||||||
|  | 	v2 result = {a.y, -a.x}; | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| INTERNAL inline v3 v3_cross(const v3 a, const v3 b) | INTERNAL inline v3 v3_cross(const v3 a, const v3 b) | ||||||
| { | { | ||||||
| 	/*
 | 	/*
 | ||||||
|  | |||||||
| @ -25,10 +25,6 @@ typedef struct RenderTex | |||||||
| 	v4 texRect; | 	v4 texRect; | ||||||
| } RenderTex; | } RenderTex; | ||||||
| 
 | 
 | ||||||
| typedef struct TrianglePoints { |  | ||||||
| 	v2 points[3]; |  | ||||||
| } TrianglePoints; |  | ||||||
| 
 |  | ||||||
| typedef u32 RenderFlags; | typedef u32 RenderFlags; | ||||||
| enum RenderFlag { | enum RenderFlag { | ||||||
| 	renderflag_wireframe = 0x1, | 	renderflag_wireframe = 0x1, | ||||||
| @ -41,7 +37,6 @@ enum RenderFlag { | |||||||
| enum RenderMode | enum RenderMode | ||||||
| { | { | ||||||
| 	rendermode_quad, | 	rendermode_quad, | ||||||
| 	rendermode_triangle, |  | ||||||
| 	rendermode_polygon, | 	rendermode_polygon, | ||||||
| 	rendermode_count, | 	rendermode_count, | ||||||
| 	rendermode_invalid, | 	rendermode_invalid, | ||||||
| @ -111,10 +106,6 @@ inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size, | |||||||
| 	              renderTex, color, flags); | 	              renderTex, color, flags); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void renderer_triangle(Renderer *const renderer, Rect camera, |  | ||||||
|                        TrianglePoints triangle, v2 pivotPoint, Radians rotate, |  | ||||||
|                        RenderTex *renderTex, v4 color, RenderFlags flags); |  | ||||||
| 
 |  | ||||||
| void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | ||||||
|                      Font *const font, const char *const string, v2 pos, |                      Font *const font, const char *const string, v2 pos, | ||||||
|                      v2 pivotPoint, Radians rotate, v4 color, |                      v2 pivotPoint, Radians rotate, v4 color, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user