Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions include/common/Camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
#include "common/Vector.h"

enum Camera_Mode {
CM_FIRST = 0,
//
CM_COUNT = 3,
CM_FIRST = 0,
CM_0 = 0,
CM_1 = 1,
CM_2 = 2,
CM_COUNT = 3,
};

enum Camera_Direction {

CD_0 = 0,
CD_1 = 1,
CD_2 = 2,
};

struct KeyMap {
Expand Down Expand Up @@ -40,7 +44,7 @@ struct Camera {
bool Update(InputDevices device, Vector*);

Camera_Mode mode;
int unk4;
Camera_Direction direction;
KeyMap* pMap;
float unkC;
Vector pos;
Expand Down
7 changes: 3 additions & 4 deletions include/ty/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,7 @@ Vector* Tools_GetRefPointPos(Model* pModel, char*);

void Tools_ApplyFrictionAndGravity(Vector*, Vector*, Vector*, float);

// Tools_RandomRadialVectorXZ__FR6Vector
void Tools_RandomRadialVectorXZ(Vector&); // might be the wrong signature
void Tools_RandomRadialVectorXZ(Vector&);
Vector* Tools_RandomNormal(Vector*);

float Tools_TurnToAngle(float currentAngle, float maxAngle, float maxTurnAngle);
Expand All @@ -266,8 +265,8 @@ struct Tools_DynamicStringTable {

void Tools_EnableWideScreen(View* pView, bool bEnableWideScreen);

float Tools_CylinderTest(Vector*, Vector*, float radius, Vector* pTestPoint);
bool Tools_CapsuleTest(Vector*, Vector*, float, float, Vector*);
float Tools_CylinderTest(Vector* pStart, Vector* pEnd, float radius, Vector* pTestPoint);
bool Tools_CapsuleTest(Vector* pStart, Vector* pEnd, float capsuleRadius, float cylinderRadius, Vector* pTestPoint);

#define NUM_PADKEYS 16
struct PadKey {
Expand Down
30 changes: 15 additions & 15 deletions src/common/Source/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ void Camera::DeinitModule(void) {
void Camera::Init(void) {
pMap = keyMapDS;

mode = (Camera_Mode)0;
unk4 = 2;
mode = CM_0;
direction = CD_2;
unkC = 1.0f;

pos.Set(0.0f, 0.0f, -10.0f);
Expand Down Expand Up @@ -104,7 +104,7 @@ void Camera::Reposition(Camera_Mode camMode, Vector* pPosition, Vector* pTarget)
#endif // defined(BARBIE_ICESKATING) && BARBIE_ICESKATING == 1

mode = camMode;
unk4 = (Camera_Direction)2;
direction = CD_2;
pos = *pPosition;
target = *pTarget;

Expand All @@ -115,16 +115,16 @@ void Camera::Reposition(Camera_Mode camMode, Vector* pPosition, Vector* pTarget)
}

void Camera::SetMode(Camera_Mode camMode) {
if (mode != (int)camMode) {
if (mode != camMode) {
mode = camMode;
}
}

void Camera::SetFixedDir(Camera_Direction camDir) {
unk40.w = 1.0f;

if (unk4 != (int)camDir) {
unk4 = camDir;
if (direction != camDir) {
direction = camDir;
}
}

Expand Down Expand Up @@ -220,12 +220,12 @@ bool Camera::Update(InputDevices device, Vector* p) {
SetMode((Camera_Mode)(mode + 1));
}

if (p == NULL && mode != 0) {
SetMode((Camera_Mode)0);
if (p == NULL && mode != CM_0) {
SetMode(CM_0);
}

if (bChangeDir) {
SetFixedDir((Camera_Direction)(unk4 + 1));
SetFixedDir((Camera_Direction)(direction + 1));
}

if (unk40.w == 1.0f && (Abs<float>(f27) > 1e-06f || Abs<float>(f22) > 1e-06f)) {
Expand All @@ -241,7 +241,7 @@ bool Camera::Update(InputDevices device, Vector* p) {
float mag;

switch (mode) {
case 0:
case CM_0:
ySignMod = 1.0f;
if (Abs<float>(f23) > 1e-06f) {
tempv.Set(0.0f, f23 * 0.2f, 0.0f);
Expand All @@ -263,7 +263,7 @@ bool Camera::Update(InputDevices device, Vector* p) {
pos.Add(&tempv);
}
break;
case 1:
case CM_1:
if (bChangeMode) {
tempv.Sub(p, &pos);
dir.w = tempv.Magnitude();
Expand Down Expand Up @@ -293,7 +293,7 @@ bool Camera::Update(InputDevices device, Vector* p) {
target = *p;
}
break;
case 2:
case CM_2:
if (bChangeMode) {
tempv.Sub(p, &pos);
dir.w = tempv.Magnitude();
Expand Down Expand Up @@ -401,11 +401,11 @@ bool Camera::Update(InputDevices device, Vector* p) {
}

switch (mode) {
case 0:
case CM_0:
target.Add(&pos, &dir);
break;
case 1:
case 2:
case CM_1:
case CM_2:
tempv.Sub(&pos, &target);
mag = tempv.Magnitude();
if (mag - dir.w > scaledSpeed * 0.2f) {
Expand Down
108 changes: 75 additions & 33 deletions src/common/Source/Collision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,21 +310,37 @@ static void NearestPointOnPolyEdge(Vector* pVec, Vector* pVec1, int* indices, in
}
}

float CylTest_CapsFirst(Vector* pVec, Vector* pVec1, float param_3, float param_4, Vector* pVec2) {
float x0 = pVec1->x - pVec->x;
float y0 = pVec1->y - pVec->y;
float z0 = pVec1->z - pVec->z;
float x1 = pVec2->x - pVec->x;
float y1 = pVec2->y - pVec->y;
float z1 = pVec2->z - pVec->z;
float local_3C = (x1 * x0) + (y1 * y0) + (z1 * z0);
if (local_3C < 0.0f || local_3C > param_3) {
/// @brief
/// @param pStart Start point the cylinder axis (A).
/// @param pEnd End point the cylinder axis B).
/// @param axisLenSq Squared length of the axis segment, |B - A|^2.
/// The caller must precompute this (e.g. v.MagSquared()).
/// Must be > 0, since it is used as a divisor.
/// @param param_4
/// @param pPoint The point to test (P).
/// @return
float CylTest_CapsFirst(Vector* pStart, Vector* pEnd, float axisLenSq, float param_4, Vector* pPoint) {
float x0 = pEnd->x - pStart->x;
float y0 = pEnd->y - pStart->y;
float z0 = pEnd->z - pStart->z;

float x1 = pPoint->x - pStart->x;
float y1 = pPoint->y - pStart->y;
float z1 = pPoint->z - pStart->z;

float projDot = (x1 * x0) + (y1 * y0) + (z1 * z0);

// Check if projection lies between A and B
if (projDot < 0.0f || projDot > axisLenSq) {
return -1.0f;
}
float t = (x1 * x1) + (y1 * y1) + (z1 * z1) - (local_3C * local_3C) / (param_3);

float t = (x1 * x1) + (y1 * y1) + (z1 * z1) - ((projDot * projDot) / axisLenSq);

if (t > param_4) {
return -1.0f;
}

return t;
}

Expand Down Expand Up @@ -354,10 +370,20 @@ static bool PointInPoly(Vector* pVec, Vector* pVec1, Vector* pVec2, int* indices
return !IsPointOnFrontSide(pVec, pVec1, &pVec2[indices[nmbrOfVertices - 1]], &pVec2[indices[0]]);
}

float SubDot(Vector* vec, Vector* vec1, Vector* vec2) {
Vector tmp;
tmp.Sub(vec, vec1);
return tmp.Dot(vec2);
/// @brief Computes the signed distance from a point to a plane, defined by a point on
/// the plane and the plane's normal: (pPoint - pPlanePoint) . pPlaneNormal
///
/// The result is positive when pPoint is on the side the normal faces, negative
/// on the opposite side, and zero when pPoint lies on the plane.
///
/// @param pPoint The point being tested.
/// @param pPlanePoint Any point on the plane.
/// @param pPlaneNormal The plane's normal (expected to be normalized).
/// @return Signed distance from the plane to pPoint.
float SignedDistanceToPlane(Vector* pPoint, Vector* pPlanePoint, Vector* pPlaneNormal) {
Vector v;
v.Sub(pPoint, pPlanePoint);
return v.Dot(pPlaneNormal);
}

static bool SweepSphereToPoly(SphereRay* pRay, Vector* pVectors, int* indices, int numVerts, Vector* arg5, Vector* arg6, CollisionResult* pResult) {
Expand All @@ -369,7 +395,7 @@ static bool SweepSphereToPoly(SphereRay* pRay, Vector* pVectors, int* indices, i
return false;
}

float d = SubDot(&pRay->mStart, &pVectors[indices[0]], arg5);
float d = SignedDistanceToPlane(&pRay->mStart, &pVectors[indices[0]], arg5);
if (d > pRay->mLength + pRay->radius) {
return false;
}
Expand Down Expand Up @@ -446,7 +472,7 @@ static bool SweepSphereToTri(SphereRay* pRay, Vector* pVert0, Vector* pVert1,
return false;
}

float d = SubDot(&pRay->mStart, pVert0, pVec3);
float d = SignedDistanceToPlane(&pRay->mStart, pVert0, pVec3);
if (d > pRay->mLength + pRay->radius) {
return false;
}
Expand Down Expand Up @@ -586,8 +612,13 @@ int Collision_SphereCollide(Vector* pPos, float radius, CollisionResult* pCr, in
Vector* triVert0 = (Vector*)&pItem->collisionThing->verts[0];
Vector* triVert1 = (Vector*)&pItem->collisionThing->verts[1];
Vector* triVert2 = (Vector*)&pItem->collisionThing->verts[2];
float fVar19 =
SubDot(pPos, (Vector*)&pItem->collisionThing->verts[0], (Vector*)&pItem->collisionThing->normal);

float fVar19 = SignedDistanceToPlane(
pPos,
(Vector*)&pItem->collisionThing->verts[0],
(Vector*)&pItem->collisionThing->normal
);

float fVar0 = Abs<float>(fVar19);
if (!(fVar0 > radius)) {
Vector v1;
Expand Down Expand Up @@ -728,21 +759,32 @@ bool InFrontOfItem(Vector* pPoint, Item* pItem) {
v.z * pItem->collisionThing->normal[2] >= 0.0f;
}

bool CheckItemSphereRay(Item* pItem, Vector* pVec, Vector* pVec1) {
CollisionThing* pThing = pItem->collisionThing;
bool ret = false;
if ((((pThing->verts[0].pos[1] < pVec->y && pThing->verts[1].pos[1] < pVec->y &&
pItem->collisionThing->verts[2].pos[1] < pVec->y) || (pThing->verts[0].pos[1] > pVec1->y &&
pItem->collisionThing->verts[1].pos[1] > pVec1->y && pThing->verts[2].pos[1] > pVec1->y)) ||
((pItem->collisionThing->verts[0].pos[0] < pVec->x && pThing->verts[1].pos[0] < pVec->x &&
pItem->collisionThing->verts[2].pos[0] < pVec->x) || (pThing->verts[0].pos[0] > pVec1->x &&
pItem->collisionThing->verts[1].pos[0] > pVec1->x && pThing->verts[2].pos[0] > pVec1->x)) ||
((pItem->collisionThing->verts[0].pos[2] < pVec->z && pThing->verts[1].pos[2] < pVec->z &&
pItem->collisionThing->verts[2].pos[2] < pVec->z) || (pThing->verts[0].pos[2] > pVec1->z &&
pItem->collisionThing->verts[1].pos[2] > pVec1->z && pThing->verts[2].pos[2] > pVec1->z)))) {
ret = true;
}
return ret;
bool CheckItemSphereRay(Item* pItem, Vector* pRayMinPos, Vector* pRayMaxPos) {
return (
pItem->collisionThing->verts[0].pos[1] < pRayMinPos->y &&
pItem->collisionThing->verts[1].pos[1] < pRayMinPos->y &&
pItem->collisionThing->verts[2].pos[1] < pRayMinPos->y
) || (
pItem->collisionThing->verts[0].pos[1] > pRayMaxPos->y &&
pItem->collisionThing->verts[1].pos[1] > pRayMaxPos->y &&
pItem->collisionThing->verts[2].pos[1] > pRayMaxPos->y
) || (
pItem->collisionThing->verts[0].pos[0] < pRayMinPos->x &&
pItem->collisionThing->verts[1].pos[0] < pRayMinPos->x &&
pItem->collisionThing->verts[2].pos[0] < pRayMinPos->x
) || (
pItem->collisionThing->verts[0].pos[0] > pRayMaxPos->x &&
pItem->collisionThing->verts[1].pos[0] > pRayMaxPos->x &&
pItem->collisionThing->verts[2].pos[0] > pRayMaxPos->x
) || (
pItem->collisionThing->verts[0].pos[2] < pRayMinPos->z &&
pItem->collisionThing->verts[1].pos[2] < pRayMinPos->z &&
pItem->collisionThing->verts[2].pos[2] < pRayMinPos->z
) || (
pItem->collisionThing->verts[0].pos[2] > pRayMaxPos->z &&
pItem->collisionThing->verts[1].pos[2] > pRayMaxPos->z &&
pItem->collisionThing->verts[2].pos[2] > pRayMaxPos->z
);
}

/// @brief Tests if a collision occurs against a poly from the ray formed by vectors pStart and pEnd
Expand Down
56 changes: 34 additions & 22 deletions src/ty/source/tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,8 +669,13 @@ bool Tools_TestFloor(Vector* pt, CollisionResult* pCr, float f1, bool bCollision
CollisionResult localCR;
pCr = pCr ? pCr : &localCR;
Vector end = {pt->x, pt->y - f1, pt->z};
return Collision_RayCollide(pt, &end, pCr,
bCollisionMode ? COLLISION_MODE_ALL : COLLISION_MODE_POLY, 0);

return Collision_RayCollide(
pt, &end,
pCr,
bCollisionMode ? COLLISION_MODE_ALL : COLLISION_MODE_POLY,
0
);
}

// Returns the y coordinate of the floor under pPos
Expand All @@ -679,10 +684,16 @@ float Tools_GetFloor(const Vector& pPos, CollisionResult* pCr, float maxRayDist,
CollisionResult localCR;
pCr = pCr ? pCr : &localCR;
Vector end = {pPos.x, pPos.y - maxRayDist, pPos.z};
if (Collision_RayCollide((Vector*)&pPos, &end, pCr,
bCollisionMode ? COLLISION_MODE_ALL : COLLISION_MODE_POLY, collisionFlags)) {

if (Collision_RayCollide(
(Vector*)&pPos, &end,
pCr,
bCollisionMode ? COLLISION_MODE_ALL : COLLISION_MODE_POLY,
collisionFlags
)) {
return pCr->pos.y;
}

return pPos.y;
}

Expand Down Expand Up @@ -1515,34 +1526,35 @@ bool Tools_SideOfLine2D(Vector* pVec, Vector* pVec1, Vector* pVec2) {
// return f0;
// }

// pVec is the bottom of the cylinder?
// pVec1 is the top of the cylinder?
float Tools_CylinderTest(Vector* pVec, Vector* pVec1, float radius, Vector* pTestPoint) {
float Tools_CylinderTest(Vector* pStart, Vector* pEnd, float radius, Vector* pTestPoint) {
float radSq = Sqr<float>(radius);
Vector tmp; // difference between pVec1 and pVec (pVec1 - pVec)
Vector tmp2;
tmp.Sub(pVec1, pVec);
tmp2.Sub(pTestPoint, pVec);
float cylinderEndDist = tmp.MagSquared(); // distance between the 2 cylinder ends (pVec1, pVec)
float f1_ = tmp.Dot(&tmp2);

Vector tmp; // pEnd - pStart
Vector tmp2; // pTestPoint - pStart

tmp.Sub(pEnd, pStart);
tmp2.Sub(pTestPoint, pStart);

float axisLenSq = tmp.MagSquared();
float proj = tmp.Dot(&tmp2);

if (f1_ < 0.0f || f1_ > cylinderEndDist) {
// cylinder end test?
return -1.0f;
if (proj < 0.0f || proj > axisLenSq) {
return -1.0f; // outside the end planes
}

float f0 = tmp2.MagSquared() - ((f1_ * f1_) / cylinderEndDist);
if (f0 > radSq) {
float distSq = tmp2.MagSquared() - ((proj * proj) / axisLenSq);
if (distSq > radSq) {
return -1.0f;
}

return f0;
return distSq;
}


bool Tools_CapsuleTest(Vector* pVec, Vector* pVec1, float f1, float f2, Vector* pVec2) {
return pVec->IsInsideSphere(pVec2, f1) || pVec1->IsInsideSphere(pVec2, f1) ||
Tools_CylinderTest(pVec, pVec1, f2, pVec2) >= 0.0f;
bool Tools_CapsuleTest(Vector* pStart, Vector* pEnd, float capsuleRadius, float cylinderRadius, Vector* pTestPoint) {
return pStart->IsInsideSphere(pTestPoint, capsuleRadius) ||
pEnd->IsInsideSphere(pTestPoint, capsuleRadius) ||
Tools_CylinderTest(pStart, pEnd, cylinderRadius, pTestPoint) >= 0.0f;
}

// should this be defined here?
Expand Down
Loading
Loading