158 lines
4.9 KiB
C++
158 lines
4.9 KiB
C++
|
|
#include "entity.hpp"
|
|
/*******************************************************************************
|
|
** EntityCreate
|
|
*******************************************************************************/
|
|
void
|
|
EntityCreate(
|
|
Entity* entity,
|
|
float xp, float yp, float zp,
|
|
void (*behaviour)(Entity*))
|
|
{
|
|
memset(entity, 0, sizeof(Entity));
|
|
|
|
VectorCreate(entity->pos, xp, yp, zp);
|
|
VectorCreate(entity->scale, 1.0f, 1.0f, 1.0f);
|
|
|
|
entity->behaviour = behaviour;
|
|
entity->issolid = 0;
|
|
entity->radius = 0.0f;
|
|
}
|
|
/*******************************************************************************
|
|
** EntityRender
|
|
*******************************************************************************/
|
|
void
|
|
EntityRender(Entity* entity, Camera* camera)
|
|
{
|
|
Vector pos;
|
|
Vector poly[2];
|
|
|
|
if (entity->texture)
|
|
{
|
|
VectorTransform(pos, entity->pos, camera->matrix);
|
|
|
|
if (pos[2] > 1.0)
|
|
{
|
|
pos[1] *= camera->aspect;
|
|
|
|
float w = (entity->texture->width / 2.0f) * entity->scale[0];
|
|
float h = (entity->texture->height / 2.0f) * entity->scale[1] * camera->aspect;
|
|
|
|
poly[0][0] = pos[0] - w;
|
|
poly[0][1] = pos[1] + h;
|
|
poly[0][2] = pos[2];
|
|
|
|
poly[1][0] = pos[0] + w;
|
|
poly[1][1] = pos[1] - h;
|
|
poly[1][2] = pos[2];
|
|
|
|
PolygonProject(poly, 2, camera);
|
|
|
|
PictureCopy(
|
|
PICTURE_FX_OR,
|
|
camera->fb,
|
|
poly[0][0],
|
|
poly[0][1],
|
|
poly[1][0] + 0.9999f,
|
|
poly[1][1] + 0.9999f,
|
|
entity->texture,
|
|
0, 0,
|
|
entity->texture->width,
|
|
entity->texture->height,
|
|
camera->zb, PixelZDepth(poly[0][2]),
|
|
entity->texture->pixels[0][0]);
|
|
}
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** EntityToEntityCollision
|
|
*******************************************************************************/
|
|
void
|
|
EntityToEntityCollision(Entity* A, Entity* B)
|
|
{
|
|
Vector vector;
|
|
|
|
if (A->issolid && B->issolid)
|
|
{
|
|
VectorSubtract(vector, A->pos, B->pos);
|
|
|
|
float dist = A->radius + B->radius - VectorMagnitude(vector);
|
|
|
|
if (dist > 0.0)
|
|
{
|
|
VectorSetLength(vector, vector, dist / 2.0f);
|
|
VectorAddition(A->vel, A->vel, vector);
|
|
VectorAddition(A->pos, A->pos, vector);
|
|
VectorSubtract(B->vel, B->vel, vector);
|
|
VectorSubtract(B->pos, B->pos, vector);
|
|
}
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** EntityToWorldCollision
|
|
*******************************************************************************/
|
|
void
|
|
EntityToWorldCollision(Entity* entity, BSP* bsp, World* world)
|
|
{
|
|
Vector A;
|
|
|
|
assert(bsp && world && entity);
|
|
|
|
if (bsp->sides[0] && bsp->sides[1])
|
|
{
|
|
float dist = PlaneDistanceTo(bsp->plane, entity->pos);
|
|
|
|
if (dist < entity->radius) EntityToWorldCollision(entity, bsp->sides[1], world);
|
|
if (dist > -entity->radius) EntityToWorldCollision(entity, bsp->sides[0], world);
|
|
|
|
if (dist < entity->radius && dist > -entity->radius)
|
|
{
|
|
for (int i = 0; i < NumberOf(bsp->faces); i++)
|
|
{
|
|
if (bsp->faces[i].colour > 2)
|
|
{
|
|
dist = FaceDistanceTo(&bsp->faces[i], entity->pos, A);
|
|
|
|
if (dist < entity->radius && dist > -entity->radius)
|
|
{
|
|
entity->collision++;
|
|
|
|
VectorSubtract(A, entity->pos, A);
|
|
VectorNormalize(A, A);
|
|
|
|
if (A[1] > 0.4f) entity->isonground++;
|
|
|
|
VectorScale(A, A, entity->radius - dist);
|
|
|
|
VectorAddition(entity->pos, entity->pos, A);
|
|
VectorAddition(entity->vel, entity->vel, A);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
** EntityProcess
|
|
*******************************************************************************/
|
|
void
|
|
EntityCollisionProcess(Entity* entity, World* world)
|
|
{
|
|
entity->collision = 0;
|
|
entity->isonground = 0;
|
|
|
|
if (entity->behaviour)
|
|
{
|
|
VectorAddition(entity->pos, entity->pos, entity->vel);
|
|
|
|
if (entity->radius > 4.0f)
|
|
{
|
|
VectorInverseTransform(entity->pos, entity->pos, world->matrix);
|
|
|
|
EntityToWorldCollision(entity, world->bsp, world);
|
|
|
|
VectorInverseTransform(entity->pos, entity->pos, world->matrix);
|
|
}
|
|
}
|
|
}
|
|
|