mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-13 05:57:05 +03:00
Fixing ropes and added debug ropes drawing
This commit is contained in:
parent
08703a5d57
commit
85bb127b12
8 changed files with 924 additions and 838 deletions
|
@ -47,6 +47,9 @@
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "Game/rope.h"
|
||||||
|
|
||||||
|
using namespace TEN::Game::Rope;
|
||||||
using std::function;
|
using std::function;
|
||||||
using TEN::Renderer::g_Renderer;
|
using TEN::Renderer::g_Renderer;
|
||||||
using namespace TEN::Control::Volumes;
|
using namespace TEN::Control::Volumes;
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include "collide.h"
|
#include "collide.h"
|
||||||
#include "items.h"
|
#include "items.h"
|
||||||
#include "control/control.h"
|
#include "control/control.h"
|
||||||
|
#include "Game/rope.h"
|
||||||
|
|
||||||
|
using namespace TEN::Game::Rope;
|
||||||
|
|
||||||
/*This file has "all" lara_as/lara_col functions where Lara is interacting with an object.*/
|
/*This file has "all" lara_as/lara_col functions where Lara is interacting with an object.*/
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,12 @@
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "items.h"
|
#include "items.h"
|
||||||
|
|
||||||
|
namespace TEN::Game::Rope
|
||||||
|
{
|
||||||
PENDULUM CurrentPendulum;
|
PENDULUM CurrentPendulum;
|
||||||
PENDULUM AlternatePendulum;
|
PENDULUM AlternatePendulum;
|
||||||
ROPE_STRUCT Ropes[12];
|
std::vector<ROPE_STRUCT> Ropes;
|
||||||
int NumRopes, RopeSwing = 0;
|
int RopeSwing = 0;
|
||||||
|
|
||||||
void InitialiseRope(short itemNumber)
|
void InitialiseRope(short itemNumber)
|
||||||
{
|
{
|
||||||
|
@ -33,12 +35,12 @@ void InitialiseRope(short itemNumber)
|
||||||
pos.y = 16384;
|
pos.y = 16384;
|
||||||
pos.z = 0;
|
pos.z = 0;
|
||||||
|
|
||||||
ROPE_STRUCT* rope = &Ropes[NumRopes];
|
ROPE_STRUCT rope;
|
||||||
|
PrepareRope(&rope, &itemPos, &pos, 128, item);
|
||||||
|
|
||||||
PrepareRope(rope, &itemPos, &pos, 128, item);
|
item->triggerFlags = Ropes.size();
|
||||||
|
|
||||||
item->triggerFlags = NumRopes;
|
Ropes.push_back(rope);
|
||||||
NumRopes++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int length, ITEM_INFO* item)
|
void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int length, ITEM_INFO* item)
|
||||||
|
@ -61,11 +63,11 @@ void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int leng
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
int il = 3145728;
|
int il = 3145728;
|
||||||
|
|
||||||
for (int i = 0; i < 24; ++i)
|
for (int i = 0; i < ROPE_SEGMENTS; ++i)
|
||||||
{
|
{
|
||||||
rope->segment[i].x = (int64_t)sum * pos2->x >> 16;
|
rope->segment[i].x = (int64_t)sum * pos2->x >> FP_SHIFT;
|
||||||
rope->segment[i].y = (int64_t)sum * pos2->x >> 16;
|
rope->segment[i].y = (int64_t)sum * pos2->x >> FP_SHIFT;
|
||||||
rope->segment[i].z = (int64_t)sum * pos2->z >> 16;
|
rope->segment[i].z = (int64_t)sum * pos2->z >> FP_SHIFT;
|
||||||
|
|
||||||
rope->velocity[i].x = 0;
|
rope->velocity[i].x = 0;
|
||||||
rope->velocity[i].y = 0;
|
rope->velocity[i].y = 0;
|
||||||
|
@ -91,9 +93,9 @@ void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int leng
|
||||||
|
|
||||||
PHD_VECTOR* NormaliseRopeVector(PHD_VECTOR* vec)
|
PHD_VECTOR* NormaliseRopeVector(PHD_VECTOR* vec)
|
||||||
{
|
{
|
||||||
int x = vec->x >> 16;
|
int x = vec->x >> FP_SHIFT;
|
||||||
int y = vec->y >> 16;
|
int y = vec->y >> FP_SHIFT;
|
||||||
int z = vec->z >> 16;
|
int z = vec->z >> FP_SHIFT;
|
||||||
|
|
||||||
if (!x && !y && !z)
|
if (!x && !y && !z)
|
||||||
return vec;
|
return vec;
|
||||||
|
@ -104,44 +106,45 @@ PHD_VECTOR* NormaliseRopeVector(PHD_VECTOR* vec)
|
||||||
|
|
||||||
length = 65536 / sqrt(length);
|
length = 65536 / sqrt(length);
|
||||||
|
|
||||||
vec->x = ((int64_t) length * vec->x) / 65536;
|
vec->x = ((int64_t)length * vec->x) >> FP_SHIFT;
|
||||||
vec->y = ((int64_t) length * vec->y) / 65536;
|
vec->y = ((int64_t)length * vec->y) >> FP_SHIFT;
|
||||||
vec->z = ((int64_t) length * vec->z) / 65536;
|
vec->z = ((int64_t)length * vec->z) >> FP_SHIFT;
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _0x0046D130(ROPE_STRUCT* rope, int segmentFrame, int* x, int* y, int* z)
|
void GetRopePos(ROPE_STRUCT* rope, int segmentFrame, int* x, int* y, int* z)
|
||||||
{
|
{
|
||||||
int segment;
|
int segment;
|
||||||
short frame;
|
short frame;
|
||||||
|
|
||||||
segment = segmentFrame / 128;
|
segment = segmentFrame / 128;
|
||||||
frame = segmentFrame & 0x7F;
|
frame = segmentFrame & 0x7F;
|
||||||
*x = (rope->normalisedSegment[segment].x * frame >> 16) + (rope->meshSegment[segment].x >> 16) + rope->position.x;
|
|
||||||
*y = (rope->normalisedSegment[segment].y * frame >> 16) + (rope->meshSegment[segment].y >> 16) + rope->position.y;
|
*x = (rope->normalisedSegment[segment].x * frame >> FP_SHIFT) + (rope->meshSegment[segment].x >> FP_SHIFT) + rope->position.x;
|
||||||
*z = (rope->normalisedSegment[segment].z * frame >> 16) + (rope->meshSegment[segment].z >> 16) + rope->position.z;
|
*y = (rope->normalisedSegment[segment].y * frame >> FP_SHIFT) + (rope->meshSegment[segment].y >> FP_SHIFT) + rope->position.y;
|
||||||
|
*z = (rope->normalisedSegment[segment].z * frame >> FP_SHIFT) + (rope->meshSegment[segment].z >> FP_SHIFT) + rope->position.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DotProduct(PHD_VECTOR* u, PHD_VECTOR* v)
|
int DotProduct(PHD_VECTOR* u, PHD_VECTOR* v)
|
||||||
{
|
{
|
||||||
return (u->x * v->x + u->y * v->y + u->z * v->z) / 16384;
|
return (u->x * v->x + u->y * v->y + u->z * v->z) >> W2V_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScaleVector(PHD_VECTOR* u, int c, PHD_VECTOR* destination)
|
void ScaleVector(PHD_VECTOR* u, int c, PHD_VECTOR* destination)
|
||||||
{
|
{
|
||||||
destination->x = c * u->x / 16384;
|
destination->x = c * u->x >> W2V_SHIFT;
|
||||||
destination->y = c * u->y / 16384;
|
destination->y = c * u->y >> W2V_SHIFT;
|
||||||
destination->z = c * u->z / 16384;
|
destination->z = c * u->z >> W2V_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrossProduct(PHD_VECTOR* u, PHD_VECTOR* v, PHD_VECTOR* destination)
|
void CrossProduct(PHD_VECTOR* u, PHD_VECTOR* v, PHD_VECTOR* destination)
|
||||||
{
|
{
|
||||||
destination->x = (u->y * v->z - u->z * v->y) / 16384;
|
destination->x = (u->y * v->z - u->z * v->y) >> W2V_SHIFT;
|
||||||
destination->y = (u->z * v->x - u->x * v->z) / 16384;
|
destination->y = (u->z * v->x - u->x * v->z) >> W2V_SHIFT;
|
||||||
destination->z = (u->x * v->y - u->y * v->x) / 16384;
|
destination->z = (u->x * v->y - u->y * v->x) >> W2V_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _0x0046D420(int* matrix, short* angle)
|
void phd_GetMatrixAngles(int* matrix, short* angle)
|
||||||
{
|
{
|
||||||
angle[0] = phd_atan(sqrt(SQUARE(matrix[M22]) + SQUARE(matrix[M02])), matrix[M12]);
|
angle[0] = phd_atan(sqrt(SQUARE(matrix[M22]) + SQUARE(matrix[M02])), matrix[M12]);
|
||||||
if (matrix[M12] >= 0 && angle[0] > 0 || matrix[M12] < 0 && angle[0] < 0)
|
if (matrix[M12] >= 0 && angle[0] > 0 || matrix[M12] < 0 && angle[0] < 0)
|
||||||
|
@ -223,11 +226,11 @@ void RopeDynamics(ROPE_STRUCT* rope)
|
||||||
--rope->coiled;
|
--rope->coiled;
|
||||||
if (!rope->coiled)
|
if (!rope->coiled)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 24; ++i)
|
for (i = 0; i < ROPE_SEGMENTS; ++i)
|
||||||
rope->velocity[i].y = 0;
|
rope->velocity[i].y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rope == &Ropes[Lara.ropePtr])
|
if (Lara.ropePtr != -1 && rope == &Ropes[Lara.ropePtr])
|
||||||
{
|
{
|
||||||
pendulumPointer = &CurrentPendulum;
|
pendulumPointer = &CurrentPendulum;
|
||||||
if (CurrentPendulum.node != Lara.ropeSegment + 1)
|
if (CurrentPendulum.node != Lara.ropeSegment + 1)
|
||||||
|
@ -250,9 +253,11 @@ void RopeDynamics(ROPE_STRUCT* rope)
|
||||||
CurrentPendulum.Position.x = 0;
|
CurrentPendulum.Position.x = 0;
|
||||||
CurrentPendulum.Position.y = 0;
|
CurrentPendulum.Position.y = 0;
|
||||||
CurrentPendulum.Position.z = 0;
|
CurrentPendulum.Position.z = 0;
|
||||||
|
|
||||||
CurrentPendulum.Velocity.x = 0;
|
CurrentPendulum.Velocity.x = 0;
|
||||||
CurrentPendulum.Velocity.y = 0;
|
CurrentPendulum.Velocity.y = 0;
|
||||||
CurrentPendulum.Velocity.z = 0;
|
CurrentPendulum.Velocity.z = 0;
|
||||||
|
|
||||||
CurrentPendulum.node = -1;
|
CurrentPendulum.node = -1;
|
||||||
CurrentPendulum.Rope = NULL;
|
CurrentPendulum.Rope = NULL;
|
||||||
}
|
}
|
||||||
|
@ -263,24 +268,29 @@ void RopeDynamics(ROPE_STRUCT* rope)
|
||||||
vec.y = pendulumPointer->Position.y - rope->segment[0].y;
|
vec.y = pendulumPointer->Position.y - rope->segment[0].y;
|
||||||
vec.z = pendulumPointer->Position.z - rope->segment[0].z;
|
vec.z = pendulumPointer->Position.z - rope->segment[0].z;
|
||||||
NormaliseRopeVector(&vec);
|
NormaliseRopeVector(&vec);
|
||||||
|
|
||||||
for (i = pendulumPointer->node; i >= 0; --i)
|
for (i = pendulumPointer->node; i >= 0; --i)
|
||||||
{
|
{
|
||||||
rope->segment[i].x = rope->meshSegment[i - 1].x + ((int64_t)rope->segmentLength * vec.x >> 16);
|
rope->segment[i].x = rope->meshSegment[i - 1].x + ((int64_t)rope->segmentLength * vec.x >> FP_SHIFT);
|
||||||
rope->segment[i].y = rope->meshSegment[i - 1].y + ((int64_t)rope->segmentLength * vec.y >> 16);
|
rope->segment[i].y = rope->meshSegment[i - 1].y + ((int64_t)rope->segmentLength * vec.y >> FP_SHIFT);
|
||||||
rope->segment[i].z = rope->meshSegment[i - 1].z + ((int64_t)rope->segmentLength * vec.z >> 16);
|
rope->segment[i].z = rope->meshSegment[i - 1].z + ((int64_t)rope->segmentLength * vec.z >> FP_SHIFT);
|
||||||
|
|
||||||
rope->velocity[i].x = 0;
|
rope->velocity[i].x = 0;
|
||||||
rope->velocity[i].y = 0;
|
rope->velocity[i].y = 0;
|
||||||
rope->velocity[i].z = 0;
|
rope->velocity[i].z = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
vec2.x = pendulumPointer->Position.x - rope->segment[pendulumPointer->node].x;
|
vec2.x = pendulumPointer->Position.x - rope->segment[pendulumPointer->node].x;
|
||||||
vec2.y = pendulumPointer->Position.y - rope->segment[pendulumPointer->node].y;
|
vec2.y = pendulumPointer->Position.y - rope->segment[pendulumPointer->node].y;
|
||||||
vec2.z = pendulumPointer->Position.z - rope->segment[pendulumPointer->node].z;
|
vec2.z = pendulumPointer->Position.z - rope->segment[pendulumPointer->node].z;
|
||||||
|
|
||||||
rope->segment[pendulumPointer->node].x = pendulumPointer->Position.x;
|
rope->segment[pendulumPointer->node].x = pendulumPointer->Position.x;
|
||||||
rope->segment[pendulumPointer->node].y = pendulumPointer->Position.y;
|
rope->segment[pendulumPointer->node].y = pendulumPointer->Position.y;
|
||||||
rope->segment[pendulumPointer->node].z = pendulumPointer->Position.z;
|
rope->segment[pendulumPointer->node].z = pendulumPointer->Position.z;
|
||||||
for (i = pendulumPointer->node; i < 24; ++i)
|
|
||||||
|
for (i = pendulumPointer->node; i < ROPE_SEGMENTS; ++i)
|
||||||
{
|
{
|
||||||
rope->segment[i].x -= vec2.x;
|
rope->segment[i].x -= vec2.x;
|
||||||
rope->segment[i].y -= vec2.y;
|
rope->segment[i].y -= vec2.y;
|
||||||
|
@ -300,13 +310,15 @@ void RopeDynamics(ROPE_STRUCT* rope)
|
||||||
}
|
}
|
||||||
for (i = pendulumPointer->node; i < 23; ++i)
|
for (i = pendulumPointer->node; i < 23; ++i)
|
||||||
_0x0046DF00(&rope->segment[i], &rope->segment[i + 1], &rope->velocity[i], &rope->velocity[i + 1], rope->segmentLength);
|
_0x0046DF00(&rope->segment[i], &rope->segment[i + 1], &rope->velocity[i], &rope->velocity[i + 1], rope->segmentLength);
|
||||||
for (i = 0; i < 24; ++i)
|
|
||||||
|
for (i = 0; i < ROPE_SEGMENTS; ++i)
|
||||||
{
|
{
|
||||||
rope->segment[i].x += rope->velocity[i].x;
|
rope->segment[i].x += rope->velocity[i].x;
|
||||||
rope->segment[i].y += rope->velocity[i].y;
|
rope->segment[i].y += rope->velocity[i].y;
|
||||||
rope->segment[i].z += rope->velocity[i].z;
|
rope->segment[i].z += rope->velocity[i].z;
|
||||||
}
|
}
|
||||||
for (i = pendulumPointer->node; i < 24; ++i)
|
|
||||||
|
for (i = pendulumPointer->node; i < ROPE_SEGMENTS; ++i)
|
||||||
{
|
{
|
||||||
rope->velocity[i].y += 196608;
|
rope->velocity[i].y += 196608;
|
||||||
if (pendulumPointer->Rope)
|
if (pendulumPointer->Rope)
|
||||||
|
@ -323,29 +335,34 @@ void RopeDynamics(ROPE_STRUCT* rope)
|
||||||
rope->segment[0].x = 0;
|
rope->segment[0].x = 0;
|
||||||
rope->segment[0].y = 0;
|
rope->segment[0].y = 0;
|
||||||
rope->segment[0].z = 0;
|
rope->segment[0].z = 0;
|
||||||
|
|
||||||
rope->velocity[0].x = 0;
|
rope->velocity[0].x = 0;
|
||||||
rope->velocity[0].y = 0;
|
rope->velocity[0].y = 0;
|
||||||
rope->velocity[0].z = 0;
|
rope->velocity[0].z = 0;
|
||||||
for (i = 0; i < 23; ++i)
|
|
||||||
|
for (i = 0; i < ROPE_SEGMENTS - 1; ++i)
|
||||||
{
|
{
|
||||||
rope->normalisedSegment[i].x = rope->segment[i + 1].x - rope->segment[i].x;
|
rope->normalisedSegment[i].x = rope->segment[i + 1].x - rope->segment[i].x;
|
||||||
rope->normalisedSegment[i].y = rope->segment[i + 1].y - rope->segment[i].y;
|
rope->normalisedSegment[i].y = rope->segment[i + 1].y - rope->segment[i].y;
|
||||||
rope->normalisedSegment[i].z = rope->segment[i + 1].z - rope->segment[i].z;
|
rope->normalisedSegment[i].z = rope->segment[i + 1].z - rope->segment[i].z;
|
||||||
NormaliseRopeVector(&rope->normalisedSegment[i]);
|
NormaliseRopeVector(&rope->normalisedSegment[i]);
|
||||||
}
|
}
|
||||||
if (rope != &Ropes[Lara.ropePtr])
|
|
||||||
|
if (Lara.ropePtr != -1 && rope != &Ropes[Lara.ropePtr])
|
||||||
{
|
{
|
||||||
rope->meshSegment[0].x = rope->segment[0].x;
|
rope->meshSegment[0].x = rope->segment[0].x;
|
||||||
rope->meshSegment[0].y = rope->segment[0].y;
|
rope->meshSegment[0].y = rope->segment[0].y;
|
||||||
rope->meshSegment[0].z = rope->segment[0].z;
|
rope->meshSegment[0].z = rope->segment[0].z;
|
||||||
rope->meshSegment[1].x = rope->segment[0].x + ((int64_t)rope->segmentLength * rope->normalisedSegment[0].x >> 16);
|
|
||||||
rope->meshSegment[1].y = rope->segment[0].y + ((int64_t)rope->segmentLength * rope->normalisedSegment[0].y >> 16);
|
rope->meshSegment[1].x = rope->segment[0].x + ((int64_t)rope->segmentLength * rope->normalisedSegment[0].x >> FP_SHIFT);
|
||||||
rope->meshSegment[1].z = rope->segment[0].z + ((int64_t)rope->segmentLength * rope->normalisedSegment[0].z >> 16);
|
rope->meshSegment[1].y = rope->segment[0].y + ((int64_t)rope->segmentLength * rope->normalisedSegment[0].y >> FP_SHIFT);
|
||||||
for (i = 2; i < 24; ++i)
|
rope->meshSegment[1].z = rope->segment[0].z + ((int64_t)rope->segmentLength * rope->normalisedSegment[0].z >> FP_SHIFT);
|
||||||
|
|
||||||
|
for (i = 2; i < ROPE_SEGMENTS; i++)
|
||||||
{
|
{
|
||||||
rope->meshSegment[i].x = rope->meshSegment[i - 1].x + ((int64_t)rope->segmentLength * rope->normalisedSegment[i - 1].x >> 16);
|
rope->meshSegment[i].x = rope->meshSegment[i - 1].x + ((int64_t)rope->segmentLength * rope->normalisedSegment[i - 1].x >> FP_SHIFT);
|
||||||
rope->meshSegment[i].y = rope->meshSegment[i - 1].y + ((int64_t)rope->segmentLength * rope->normalisedSegment[i - 1].y >> 16);
|
rope->meshSegment[i].y = rope->meshSegment[i - 1].y + ((int64_t)rope->segmentLength * rope->normalisedSegment[i - 1].y >> FP_SHIFT);
|
||||||
rope->meshSegment[i].z = rope->meshSegment[i - 1].z + ((int64_t)rope->segmentLength * rope->normalisedSegment[i - 1].z >> 16);
|
rope->meshSegment[i].z = rope->meshSegment[i - 1].z + ((int64_t)rope->segmentLength * rope->normalisedSegment[i - 1].z >> FP_SHIFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -353,16 +370,19 @@ void RopeDynamics(ROPE_STRUCT* rope)
|
||||||
rope->meshSegment[pendulumPointer->node].x = rope->segment[pendulumPointer->node].x;
|
rope->meshSegment[pendulumPointer->node].x = rope->segment[pendulumPointer->node].x;
|
||||||
rope->meshSegment[pendulumPointer->node].y = rope->segment[pendulumPointer->node].y;
|
rope->meshSegment[pendulumPointer->node].y = rope->segment[pendulumPointer->node].y;
|
||||||
rope->meshSegment[pendulumPointer->node].z = rope->segment[pendulumPointer->node].z;
|
rope->meshSegment[pendulumPointer->node].z = rope->segment[pendulumPointer->node].z;
|
||||||
rope->meshSegment[pendulumPointer->node + 1].x = rope->segment[pendulumPointer->node].x + ((int64_t)rope->segmentLength * rope->normalisedSegment[pendulumPointer->node].x >> 16);
|
|
||||||
rope->meshSegment[pendulumPointer->node + 1].y = rope->segment[pendulumPointer->node].y + ((int64_t)rope->segmentLength * rope->normalisedSegment[pendulumPointer->node].y >> 16);
|
rope->meshSegment[pendulumPointer->node + 1].x = rope->segment[pendulumPointer->node].x + ((int64_t)rope->segmentLength * rope->normalisedSegment[pendulumPointer->node].x >> FP_SHIFT);
|
||||||
rope->meshSegment[pendulumPointer->node + 1].z = rope->segment[pendulumPointer->node].z + ((int64_t)rope->segmentLength * rope->normalisedSegment[pendulumPointer->node].z >> 16);
|
rope->meshSegment[pendulumPointer->node + 1].y = rope->segment[pendulumPointer->node].y + ((int64_t)rope->segmentLength * rope->normalisedSegment[pendulumPointer->node].y >> FP_SHIFT);
|
||||||
for (i = pendulumPointer->node + 1; i < 23; ++i)
|
rope->meshSegment[pendulumPointer->node + 1].z = rope->segment[pendulumPointer->node].z + ((int64_t)rope->segmentLength * rope->normalisedSegment[pendulumPointer->node].z >> FP_SHIFT);
|
||||||
|
|
||||||
|
for (i = pendulumPointer->node + 1; i < ROPE_SEGMENTS - 1; ++i)
|
||||||
{
|
{
|
||||||
rope->meshSegment[i + 1].x = rope->meshSegment[i].x + ((int64_t)rope->segmentLength * rope->normalisedSegment[i].x >> 16);
|
rope->meshSegment[i + 1].x = rope->meshSegment[i].x + ((int64_t)rope->segmentLength * rope->normalisedSegment[i].x >> FP_SHIFT);
|
||||||
rope->meshSegment[i + 1].y = rope->meshSegment[i].y + ((int64_t)rope->segmentLength * rope->normalisedSegment[i].y >> 16);
|
rope->meshSegment[i + 1].y = rope->meshSegment[i].y + ((int64_t)rope->segmentLength * rope->normalisedSegment[i].y >> FP_SHIFT);
|
||||||
rope->meshSegment[i + 1].z = rope->meshSegment[i].z + ((int64_t)rope->segmentLength * rope->normalisedSegment[i].z >> 16);
|
rope->meshSegment[i + 1].z = rope->meshSegment[i].z + ((int64_t)rope->segmentLength * rope->normalisedSegment[i].z >> FP_SHIFT);
|
||||||
}
|
}
|
||||||
for (i = 0; i < pendulumPointer->node; ++i)
|
|
||||||
|
for (i = 0; i < pendulumPointer->node; i++)
|
||||||
{
|
{
|
||||||
rope->meshSegment[i].x = rope->segment[i].x;
|
rope->meshSegment[i].x = rope->segment[i].x;
|
||||||
rope->meshSegment[i].y = rope->segment[i].y;
|
rope->meshSegment[i].y = rope->segment[i].y;
|
||||||
|
@ -375,13 +395,14 @@ int _0x0046D200(ROPE_STRUCT* rope, int x, int y, int z, int radius)
|
||||||
{
|
{
|
||||||
int dx, dy, dz;
|
int dx, dy, dz;
|
||||||
|
|
||||||
for (int i = 0; i < 22; ++i)
|
for (int i = 0; i < ROPE_SEGMENTS - 2; ++i)
|
||||||
{
|
{
|
||||||
if (y > rope->position.y + (rope->meshSegment[i].y / 65536) && y < rope->position.y + (rope->meshSegment[i + 1].y / 65536))
|
if (y > rope->position.y + (rope->meshSegment[i].y >> FP_SHIFT)
|
||||||
|
&& y < rope->position.y + (rope->meshSegment[i + 1].y >> FP_SHIFT))
|
||||||
{
|
{
|
||||||
dx = x - ((rope->meshSegment[i + 1].x + rope->meshSegment[i].x) / 131072) - rope->position.x;
|
dx = x - ((rope->meshSegment[i + 1].x + rope->meshSegment[i].x) >> (FP_SHIFT + 1)) - rope->position.x;
|
||||||
dy = y - ((rope->meshSegment[i + 1].y + rope->meshSegment[i].y) / 131072) - rope->position.y;
|
dy = y - ((rope->meshSegment[i + 1].y + rope->meshSegment[i].y) >> (FP_SHIFT + 1)) - rope->position.y;
|
||||||
dz = z - ((rope->meshSegment[i + 1].z + rope->meshSegment[i].z) / 131072) - rope->position.z;
|
dz = z - ((rope->meshSegment[i + 1].z + rope->meshSegment[i].z) >> (FP_SHIFT + 1)) - rope->position.z;
|
||||||
if (SQUARE(dx) + SQUARE(dy) + SQUARE(dz) < SQUARE(radius + 64))
|
if (SQUARE(dx) + SQUARE(dy) + SQUARE(dz) < SQUARE(radius + 64))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -402,13 +423,13 @@ void SetPendulumVelocity(int x, int y, int z)
|
||||||
int node;
|
int node;
|
||||||
|
|
||||||
node = 2 * (CurrentPendulum.node >> 1);
|
node = 2 * (CurrentPendulum.node >> 1);
|
||||||
if (node < 24)
|
if (node < ROPE_SEGMENTS)
|
||||||
{
|
{
|
||||||
int val = 4096 / (24 - node) * 256;
|
int val = 4096 / (ROPE_SEGMENTS - node) * 256;
|
||||||
|
|
||||||
x = (int64_t)val * x >> 16;
|
x = (int64_t)val * x >> FP_SHIFT;
|
||||||
y = (int64_t)val * y >> 16;
|
y = (int64_t)val * y >> FP_SHIFT;
|
||||||
z = (int64_t)val * z >> 16;
|
z = (int64_t)val * z >> FP_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentPendulum.Velocity.x += x;
|
CurrentPendulum.Velocity.x += x;
|
||||||
|
@ -421,12 +442,14 @@ void _0x0046E1C0(ROPE_STRUCT* rope, int node)
|
||||||
CurrentPendulum.Position.x = rope->segment[node].x;
|
CurrentPendulum.Position.x = rope->segment[node].x;
|
||||||
CurrentPendulum.Position.y = rope->segment[node].y;
|
CurrentPendulum.Position.y = rope->segment[node].y;
|
||||||
CurrentPendulum.Position.z = rope->segment[node].z;
|
CurrentPendulum.Position.z = rope->segment[node].z;
|
||||||
|
|
||||||
if (CurrentPendulum.node == -1)
|
if (CurrentPendulum.node == -1)
|
||||||
{
|
{
|
||||||
CurrentPendulum.Velocity.x += rope->velocity[node].x;
|
CurrentPendulum.Velocity.x += rope->velocity[node].x;
|
||||||
CurrentPendulum.Velocity.y += rope->velocity[node].y;
|
CurrentPendulum.Velocity.y += rope->velocity[node].y;
|
||||||
CurrentPendulum.Velocity.z += rope->velocity[node].z;
|
CurrentPendulum.Velocity.z += rope->velocity[node].z;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentPendulum.node = node;
|
CurrentPendulum.node = node;
|
||||||
CurrentPendulum.Rope = rope;
|
CurrentPendulum.Rope = rope;
|
||||||
}
|
}
|
||||||
|
@ -439,11 +462,13 @@ void _0x0046E080(ROPE_STRUCT* rope, PENDULUM* pendulumPointer, PHD_VECTOR* ropeV
|
||||||
vec.x = pendulumPointer->Position.x + pendulumVelocity->x - rope->segment[0].x;
|
vec.x = pendulumPointer->Position.x + pendulumVelocity->x - rope->segment[0].x;
|
||||||
vec.y = pendulumPointer->Position.y + pendulumVelocity->y - rope->segment[0].y;
|
vec.y = pendulumPointer->Position.y + pendulumVelocity->y - rope->segment[0].y;
|
||||||
vec.z = pendulumPointer->Position.z + pendulumVelocity->z - rope->segment[0].z;
|
vec.z = pendulumPointer->Position.z + pendulumVelocity->z - rope->segment[0].z;
|
||||||
result = 65536 * sqrt(abs(SQUARE(vec.x >> 16) + SQUARE(vec.y >> 16) + SQUARE(vec.z >> 16))) - value;
|
|
||||||
|
result = 65536 * sqrt(abs(SQUARE(vec.x >> FP_SHIFT) + SQUARE(vec.y >> FP_SHIFT) + SQUARE(vec.z >> FP_SHIFT))) - value;
|
||||||
NormaliseRopeVector(&vec);
|
NormaliseRopeVector(&vec);
|
||||||
pendulumVelocity->x -= (int64_t)result * vec.x >> 16;
|
|
||||||
pendulumVelocity->y -= (int64_t)result * vec.y >> 16;
|
pendulumVelocity->x -= (int64_t)result * vec.x >> FP_SHIFT;
|
||||||
pendulumVelocity->z -= (int64_t)result * vec.z >> 16;
|
pendulumVelocity->y -= (int64_t)result * vec.y >> FP_SHIFT;
|
||||||
|
pendulumVelocity->z -= (int64_t)result * vec.z >> FP_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _0x0046DF00(PHD_VECTOR* segment, PHD_VECTOR* nextSegment, PHD_VECTOR* velocity, PHD_VECTOR* nextVelocity, int length)
|
void _0x0046DF00(PHD_VECTOR* segment, PHD_VECTOR* nextSegment, PHD_VECTOR* velocity, PHD_VECTOR* nextVelocity, int length)
|
||||||
|
@ -454,14 +479,18 @@ void _0x0046DF00(PHD_VECTOR* segment, PHD_VECTOR* nextSegment, PHD_VECTOR* veloc
|
||||||
vec.x = nextSegment->x + nextVelocity->x - segment->x - velocity->x;
|
vec.x = nextSegment->x + nextVelocity->x - segment->x - velocity->x;
|
||||||
vec.y = nextSegment->y + nextVelocity->y - segment->y - velocity->y;
|
vec.y = nextSegment->y + nextVelocity->y - segment->y - velocity->y;
|
||||||
vec.z = nextSegment->z + nextVelocity->z - segment->z - velocity->z;
|
vec.z = nextSegment->z + nextVelocity->z - segment->z - velocity->z;
|
||||||
result = (65536 * sqrt(abs(SQUARE(vec.x >> 16) + SQUARE(vec.y >> 16) + SQUARE(vec.z >> 16))) - length) / 2;
|
|
||||||
|
result = (65536 * sqrt(abs(SQUARE(vec.x >> FP_SHIFT) + SQUARE(vec.y >> FP_SHIFT) + SQUARE(vec.z >> FP_SHIFT))) - length) / 2;
|
||||||
NormaliseRopeVector(&vec);
|
NormaliseRopeVector(&vec);
|
||||||
vec.x = (int64_t)result * vec.x >> 16;
|
|
||||||
vec.y = (int64_t)result * vec.y >> 16;
|
vec.x = (int64_t)result * vec.x >> FP_SHIFT;
|
||||||
vec.z = (int64_t)result * vec.z >> 16;
|
vec.y = (int64_t)result * vec.y >> FP_SHIFT;
|
||||||
|
vec.z = (int64_t)result * vec.z >> FP_SHIFT;
|
||||||
|
|
||||||
velocity->x += vec.x;
|
velocity->x += vec.x;
|
||||||
velocity->y += vec.y;
|
velocity->y += vec.y;
|
||||||
velocity->z += vec.z;
|
velocity->z += vec.z;
|
||||||
|
|
||||||
nextVelocity->x -= vec.x;
|
nextVelocity->x -= vec.x;
|
||||||
nextVelocity->y -= vec.y;
|
nextVelocity->y -= vec.y;
|
||||||
nextVelocity->z -= vec.z;
|
nextVelocity->z -= vec.z;
|
||||||
|
@ -603,7 +632,7 @@ void JumpOffRope(ITEM_INFO* item)
|
||||||
|
|
||||||
void FallFromRope(ITEM_INFO* item)
|
void FallFromRope(ITEM_INFO* item)
|
||||||
{
|
{
|
||||||
item->speed = abs(CurrentPendulum.Velocity.x >> 16) + abs(CurrentPendulum.Velocity.z >> 16) >> 1;
|
item->speed = abs(CurrentPendulum.Velocity.x >> FP_SHIFT) + abs(CurrentPendulum.Velocity.z >> FP_SHIFT) >> 1;
|
||||||
item->pos.xRot = 0;
|
item->pos.xRot = 0;
|
||||||
item->pos.yPos += 320;
|
item->pos.yPos += 320;
|
||||||
|
|
||||||
|
@ -679,11 +708,14 @@ void DelAlignLaraToRope(ITEM_INFO* item)
|
||||||
vec.x = 4096;
|
vec.x = 4096;
|
||||||
vec.y = 0;
|
vec.y = 0;
|
||||||
vec.z = 0;
|
vec.z = 0;
|
||||||
|
|
||||||
frame = (ANIM_FRAME*)GetBestFrame(item);
|
frame = (ANIM_FRAME*)GetBestFrame(item);
|
||||||
ropeY = Lara.ropeY - ANGLE(90);
|
ropeY = Lara.ropeY - ANGLE(90);
|
||||||
rope = &Ropes[Lara.ropePtr];
|
rope = &Ropes[Lara.ropePtr];
|
||||||
_0x0046D130(rope, (Lara.ropeSegment - 1 << 7) + frame->offsetY, &pos.x, &pos.y, &pos.z);
|
|
||||||
_0x0046D130(rope, (Lara.ropeSegment - 1 << 7) + frame->offsetY - 192, &pos2.x, &pos2.y, &pos2.z);
|
GetRopePos(rope, (Lara.ropeSegment - 1 << 7) + frame->offsetY, &pos.x, &pos.y, &pos.z);
|
||||||
|
GetRopePos(rope, (Lara.ropeSegment - 1 << 7) + frame->offsetY - 192, &pos2.x, &pos2.y, &pos2.z);
|
||||||
|
|
||||||
diff.x = pos.x - pos2.x << 16;
|
diff.x = pos.x - pos2.x << 16;
|
||||||
diff.y = pos.y - pos2.y << 16;
|
diff.y = pos.y - pos2.y << 16;
|
||||||
diff.z = pos.z - pos2.z << 16;
|
diff.z = pos.z - pos2.z << 16;
|
||||||
|
@ -695,23 +727,28 @@ void DelAlignLaraToRope(ITEM_INFO* item)
|
||||||
vec2.x = vec.x - vec2.x;
|
vec2.x = vec.x - vec2.x;
|
||||||
vec2.y = vec.y - vec2.y;
|
vec2.y = vec.y - vec2.y;
|
||||||
vec2.z = vec.z - vec2.z;
|
vec2.z = vec.z - vec2.z;
|
||||||
|
|
||||||
vec3.x = vec2.x;
|
vec3.x = vec2.x;
|
||||||
vec3.y = vec2.y;
|
vec3.y = vec2.y;
|
||||||
vec3.z = vec2.z;
|
vec3.z = vec2.z;
|
||||||
vec4.x = vec2.x;
|
vec4.x = vec2.x;
|
||||||
vec4.y = vec2.y;
|
vec4.y = vec2.y;
|
||||||
vec4.z = vec2.z;
|
vec4.z = vec2.z;
|
||||||
|
|
||||||
diff2.x = diff.x;
|
diff2.x = diff.x;
|
||||||
diff2.y = diff.y;
|
diff2.y = diff.y;
|
||||||
diff2.z = diff.z;
|
diff2.z = diff.z;
|
||||||
|
|
||||||
ScaleVector(&vec3, 16384 * phd_cos(ropeY), &vec3);
|
ScaleVector(&vec3, 16384 * phd_cos(ropeY), &vec3);
|
||||||
ScaleVector(&diff2, DotProduct(&diff2, &vec2), &diff2);
|
ScaleVector(&diff2, DotProduct(&diff2, &vec2), &diff2);
|
||||||
ScaleVector(&diff2, 4096 - 16384 * phd_cos(ropeY), &diff2);
|
ScaleVector(&diff2, 4096 - 16384 * phd_cos(ropeY), &diff2);
|
||||||
|
|
||||||
CrossProduct(&diff, &vec2, &vec4);
|
CrossProduct(&diff, &vec2, &vec4);
|
||||||
ScaleVector(&vec4, 16384 * phd_sin(ropeY), &vec4);
|
ScaleVector(&vec4, 16384 * phd_sin(ropeY), &vec4);
|
||||||
diff2.x += vec3.x;
|
diff2.x += vec3.x;
|
||||||
diff2.y += vec3.y;
|
diff2.y += vec3.y;
|
||||||
diff2.z += vec3.z;
|
diff2.z += vec3.z;
|
||||||
|
|
||||||
vec2.x = diff2.x + vec4.x << 16;
|
vec2.x = diff2.x + vec4.x << 16;
|
||||||
vec2.y = diff2.y + vec4.y << 16;
|
vec2.y = diff2.y + vec4.y << 16;
|
||||||
vec2.z = diff2.z + vec4.z << 16;
|
vec2.z = diff2.z + vec4.z << 16;
|
||||||
|
@ -719,7 +756,9 @@ void DelAlignLaraToRope(ITEM_INFO* item)
|
||||||
vec2.x >>= 2;
|
vec2.x >>= 2;
|
||||||
vec2.y >>= 2;
|
vec2.y >>= 2;
|
||||||
vec2.z >>= 2;
|
vec2.z >>= 2;
|
||||||
|
|
||||||
CrossProduct(&diff, &vec2, &vec5);
|
CrossProduct(&diff, &vec2, &vec5);
|
||||||
|
|
||||||
vec5.x <<= 16;
|
vec5.x <<= 16;
|
||||||
vec5.y <<= 16;
|
vec5.y <<= 16;
|
||||||
vec5.z <<= 16;
|
vec5.z <<= 16;
|
||||||
|
@ -727,6 +766,7 @@ void DelAlignLaraToRope(ITEM_INFO* item)
|
||||||
vec5.x >>= 2;
|
vec5.x >>= 2;
|
||||||
vec5.y >>= 2;
|
vec5.y >>= 2;
|
||||||
vec5.z >>= 2;
|
vec5.z >>= 2;
|
||||||
|
|
||||||
matrix[M00] = vec5.x;
|
matrix[M00] = vec5.x;
|
||||||
matrix[M01] = diff.x;
|
matrix[M01] = diff.x;
|
||||||
matrix[M02] = vec2.x;
|
matrix[M02] = vec2.x;
|
||||||
|
@ -736,23 +776,27 @@ void DelAlignLaraToRope(ITEM_INFO* item)
|
||||||
matrix[M20] = vec5.z;
|
matrix[M20] = vec5.z;
|
||||||
matrix[M21] = diff.z;
|
matrix[M21] = diff.z;
|
||||||
matrix[M22] = vec2.z;
|
matrix[M22] = vec2.z;
|
||||||
_0x0046D420(matrix, angle);
|
|
||||||
item->pos.xPos = rope->position.x + (rope->meshSegment[Lara.ropeSegment].x >> 16);
|
phd_GetMatrixAngles(matrix, angle);
|
||||||
item->pos.yPos = rope->position.y + (rope->meshSegment[Lara.ropeSegment].y >> 16) + Lara.ropeOffset;
|
|
||||||
item->pos.zPos = rope->position.z + (rope->meshSegment[Lara.ropeSegment].z >> 16);
|
item->pos.xPos = rope->position.x + (rope->meshSegment[Lara.ropeSegment].x >> FP_SHIFT);
|
||||||
|
item->pos.yPos = rope->position.y + (rope->meshSegment[Lara.ropeSegment].y >> FP_SHIFT) + Lara.ropeOffset;
|
||||||
|
item->pos.zPos = rope->position.z + (rope->meshSegment[Lara.ropeSegment].z >> FP_SHIFT);
|
||||||
|
|
||||||
Matrix rotMatrix = Matrix::CreateFromYawPitchRoll(
|
Matrix rotMatrix = Matrix::CreateFromYawPitchRoll(
|
||||||
TO_DEGREES(angle[1]),
|
TO_RAD(angle[1]),
|
||||||
TO_DEGREES(angle[0]),
|
TO_RAD(angle[0]),
|
||||||
TO_DEGREES(angle[2])
|
TO_RAD(angle[2])
|
||||||
);
|
);
|
||||||
|
|
||||||
// PHD_MATH!
|
rotMatrix = rotMatrix.Transpose();
|
||||||
item->pos.xPos += -112 * rotMatrix.m[0][2]; // MatrixPtr[M02] >> W2V_SHIFT;
|
|
||||||
item->pos.yPos += -112 * rotMatrix.m[1][2]; // MatrixPtr[M12] >> W2V_SHIFT;
|
item->pos.xPos += -112 * rotMatrix.m[0][2];
|
||||||
item->pos.zPos += -112 * rotMatrix.m[2][2]; // MatrixPtr[M22] >> W2V_SHIFT;
|
item->pos.yPos += -112 * rotMatrix.m[1][2];
|
||||||
|
item->pos.zPos += -112 * rotMatrix.m[2][2];
|
||||||
|
|
||||||
item->pos.xRot = angle[0];
|
item->pos.xRot = angle[0];
|
||||||
item->pos.yRot = angle[1];
|
item->pos.yRot = angle[1];
|
||||||
item->pos.zRot = angle[2];
|
item->pos.zRot = angle[2];
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "collide.h"
|
#include "collide.h"
|
||||||
|
|
||||||
|
namespace TEN::Game::Rope
|
||||||
|
{
|
||||||
struct ROPE_STRUCT
|
struct ROPE_STRUCT
|
||||||
{
|
{
|
||||||
PHD_VECTOR segment[24]; // size=288, offset=0
|
PHD_VECTOR segment[24]; // size=288, offset=0
|
||||||
|
@ -9,7 +11,7 @@ struct ROPE_STRUCT
|
||||||
PHD_VECTOR normalisedSegment[24]; // size=288, offset=576
|
PHD_VECTOR normalisedSegment[24]; // size=288, offset=576
|
||||||
PHD_VECTOR meshSegment[24]; // size=288, offset=864
|
PHD_VECTOR meshSegment[24]; // size=288, offset=864
|
||||||
PHD_VECTOR position; // size=12, offset=1152
|
PHD_VECTOR position; // size=12, offset=1152
|
||||||
PHD_VECTOR Unknown[24];
|
PHD_VECTOR coords[24];
|
||||||
int segmentLength; // size=0, offset=1164
|
int segmentLength; // size=0, offset=1164
|
||||||
short active; // size=0, offset=1168
|
short active; // size=0, offset=1168
|
||||||
short coiled; // size=0, offset=1170
|
short coiled; // size=0, offset=1170
|
||||||
|
@ -23,18 +25,22 @@ struct PENDULUM
|
||||||
ROPE_STRUCT* Rope; // size=1172, offset=28
|
ROPE_STRUCT* Rope; // size=1172, offset=28
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr auto ROPE_SEGMENTS = 24;
|
||||||
|
constexpr auto ROPE_WIDTH = 24;
|
||||||
|
|
||||||
extern PENDULUM CurrentPendulum;
|
extern PENDULUM CurrentPendulum;
|
||||||
extern ROPE_STRUCT Ropes[12];
|
extern PENDULUM AlternatePendulum;
|
||||||
extern int NumRopes;
|
extern std::vector<ROPE_STRUCT> Ropes;
|
||||||
|
extern int RopeSwing;
|
||||||
|
|
||||||
void InitialiseRope(short itemNumber);
|
void InitialiseRope(short itemNumber);
|
||||||
void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int length, ITEM_INFO* item);
|
void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int length, ITEM_INFO* item);
|
||||||
PHD_VECTOR* NormaliseRopeVector(PHD_VECTOR* vec);
|
PHD_VECTOR* NormaliseRopeVector(PHD_VECTOR* vec);
|
||||||
void _0x0046D130(ROPE_STRUCT* rope, int segmentFrame, int* x, int* y, int* z);
|
void GetRopePos(ROPE_STRUCT* rope, int segmentFrame, int* x, int* y, int* z);
|
||||||
int DotProduct(PHD_VECTOR* u, PHD_VECTOR* v);
|
int DotProduct(PHD_VECTOR* u, PHD_VECTOR* v);
|
||||||
void ScaleVector(PHD_VECTOR* src, int c, PHD_VECTOR* dest);
|
void ScaleVector(PHD_VECTOR* src, int c, PHD_VECTOR* dest);
|
||||||
void CrossProduct(PHD_VECTOR* u, PHD_VECTOR* v, PHD_VECTOR* dest);
|
void CrossProduct(PHD_VECTOR* u, PHD_VECTOR* v, PHD_VECTOR* dest);
|
||||||
void _0x0046D420(int* array, short* angle);
|
void phd_GetMatrixAngles(int* array, short* angle);
|
||||||
void RopeControl(short itemNumber);
|
void RopeControl(short itemNumber);
|
||||||
void RopeCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll);
|
void RopeCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll);
|
||||||
void RopeDynamics(ROPE_STRUCT* rope);
|
void RopeDynamics(ROPE_STRUCT* rope);
|
||||||
|
@ -49,4 +55,4 @@ void JumpOffRope(ITEM_INFO* item);
|
||||||
void FallFromRope(ITEM_INFO* item);
|
void FallFromRope(ITEM_INFO* item);
|
||||||
void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll);
|
void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll);
|
||||||
void DelAlignLaraToRope(ITEM_INFO* item);
|
void DelAlignLaraToRope(ITEM_INFO* item);
|
||||||
|
}
|
|
@ -32,6 +32,9 @@
|
||||||
#include <Objects/Effects/tr4_locusts.h>
|
#include <Objects/Effects/tr4_locusts.h>
|
||||||
#include <control\volume.h>
|
#include <control\volume.h>
|
||||||
#include "items.h"
|
#include "items.h"
|
||||||
|
#include "Game/rope.h"
|
||||||
|
|
||||||
|
using namespace TEN::Game::Rope;
|
||||||
|
|
||||||
extern TEN::Renderer::RendererHUDBar *g_DashBar;
|
extern TEN::Renderer::RendererHUDBar *g_DashBar;
|
||||||
extern TEN::Renderer::RendererHUDBar *g_SFXVolumeBar;
|
extern TEN::Renderer::RendererHUDBar *g_SFXVolumeBar;
|
||||||
|
@ -1961,120 +1964,42 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
void Renderer11::drawRopes(RenderView& view)
|
void Renderer11::drawRopes(RenderView& view)
|
||||||
{
|
{
|
||||||
for (int n = 0; n < NumRopes; n++)
|
for (int n = 0; n < Ropes.size(); n++)
|
||||||
{
|
{
|
||||||
ROPE_STRUCT* rope = &Ropes[n];
|
ROPE_STRUCT* rope = &Ropes[n];
|
||||||
|
|
||||||
if (rope->active)
|
if (rope->active)
|
||||||
{
|
{
|
||||||
// Original algorithm:
|
Matrix world = Matrix::CreateTranslation(
|
||||||
// 1) Transform segment coordinates from 3D to 2D + depth
|
rope->position.x,
|
||||||
// 2) Get dx, dy and the segment length
|
rope->position.y,
|
||||||
// 3) Get sine and cosine from dx / length and dy / length
|
rope->position.z
|
||||||
// 4) Calculate a scale factor
|
);
|
||||||
// 5) Get the coordinates of the 4 corners of each sprite iteratively
|
|
||||||
// 6) Last step only for us, unproject back to 3D coordinates
|
|
||||||
|
|
||||||
// Tranform rope points
|
Vector3 absolute[24];
|
||||||
Vector3 projected[24];
|
|
||||||
Matrix world = Matrix::Identity;
|
|
||||||
|
|
||||||
for (int i = 0; i < 24; i++)
|
for (int n = 0; n < ROPE_SEGMENTS; n++)
|
||||||
{
|
{
|
||||||
Vector3 absolutePosition = Vector3(rope->position.x + rope->segment[i].x / 65536.0f,
|
PHD_VECTOR* s = &rope->meshSegment[n];
|
||||||
rope->position.y + rope->segment[i].y / 65536.0f,
|
Vector3 t;
|
||||||
rope->position.z + rope->segment[i].z / 65536.0f);
|
Vector3 output;
|
||||||
|
|
||||||
projected[i] = m_viewportToolkit.Project(absolutePosition, Projection, View, world);
|
t.x = s->x >> FP_SHIFT;
|
||||||
|
t.y = s->y >> FP_SHIFT;
|
||||||
|
t.z = s->z >> FP_SHIFT;
|
||||||
|
|
||||||
|
output = Vector3::Transform(t, world);
|
||||||
|
|
||||||
|
Vector3 absolutePosition = Vector3(output.x, output.y, output.z);
|
||||||
|
absolute[n] = absolutePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now each rope point is transformed in screen X, Y and Z depth
|
for (int n = 0; n < ROPE_SEGMENTS - 1; n++)
|
||||||
// Let's calculate dx, dy corrections and scaling
|
|
||||||
float dx = projected[1].x - projected[0].x;
|
|
||||||
float dy = projected[1].y - projected[0].y;
|
|
||||||
float length = sqrt(dx * dx + dy * dy);
|
|
||||||
float s = 0;
|
|
||||||
float c = 0;
|
|
||||||
|
|
||||||
if (length != 0)
|
|
||||||
{
|
{
|
||||||
s = -dy / length;
|
addLine3D(absolute[n], absolute[n + 1], Vector4::One);
|
||||||
c = dx / length;
|
|
||||||
}
|
|
||||||
|
|
||||||
float w = 6.0f;
|
|
||||||
if (projected[0].z)
|
|
||||||
{
|
|
||||||
w = 6.0f * PhdPerspective / projected[0].z / 65536.0f;
|
|
||||||
if (w < 3)
|
|
||||||
w = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
float sdx = s * w;
|
|
||||||
float sdy = c * w;
|
|
||||||
|
|
||||||
float x1 = projected[0].x - sdx;
|
|
||||||
float y1 = projected[0].y - sdy;
|
|
||||||
|
|
||||||
float x2 = projected[0].x + sdx;
|
|
||||||
float y2 = projected[0].y + sdy;
|
|
||||||
|
|
||||||
float depth = projected[0].z;
|
|
||||||
|
|
||||||
for (int j = 0; j < 24; j++)
|
|
||||||
{
|
|
||||||
Vector3 p1 = m_viewportToolkit.Unproject(Vector3(x1, y1, depth), Projection, View, world);
|
|
||||||
Vector3 p2 = m_viewportToolkit.Unproject(Vector3(x2, y2, depth), Projection, View, world);
|
|
||||||
|
|
||||||
dx = projected[j].x - projected[j - 1].x;
|
|
||||||
dy = projected[j].y - projected[j - 1].y;
|
|
||||||
length = sqrt(dx * dx + dy * dy);
|
|
||||||
s = 0;
|
|
||||||
c = 0;
|
|
||||||
|
|
||||||
if (length != 0)
|
|
||||||
{
|
|
||||||
s = -dy / length;
|
|
||||||
c = dx / length;
|
|
||||||
}
|
|
||||||
|
|
||||||
w = 6.0f;
|
|
||||||
if (projected[j].z)
|
|
||||||
{
|
|
||||||
w = 6.0f * PhdPerspective / projected[j].z / 65536.0f;
|
|
||||||
if (w < 3)
|
|
||||||
w = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
float sdx = s * w;
|
|
||||||
float sdy = c * w;
|
|
||||||
|
|
||||||
float x3 = projected[j].x - sdx;
|
|
||||||
float y3 = projected[j].y - sdy;
|
|
||||||
|
|
||||||
float x4 = projected[j].x + sdx;
|
|
||||||
float y4 = projected[j].y + sdy;
|
|
||||||
|
|
||||||
depth = projected[j].z;
|
|
||||||
|
|
||||||
Vector3 p3 = m_viewportToolkit.Unproject(Vector3(x3, y3, depth), Projection, View, world);
|
|
||||||
Vector3 p4 = m_viewportToolkit.Unproject(Vector3(x4, y4, depth), Projection, View, world);
|
|
||||||
|
|
||||||
addSprite3D(&m_sprites[20],
|
|
||||||
Vector3(p1.x, p1.y, p1.z),
|
|
||||||
Vector3(p2.x, p2.y, p2.z),
|
|
||||||
Vector3(p3.x, p3.y, p3.z),
|
|
||||||
Vector3(p4.x, p4.y, p4.z),
|
|
||||||
Vector4(0.5f, 0.5f, 0.5f, 1.0f), 0, 1, { 0, 0 }, BLENDMODE_OPAQUE,view);
|
|
||||||
|
|
||||||
x1 = x4;
|
|
||||||
y1 = y4;
|
|
||||||
x2 = x3;
|
|
||||||
y2 = y3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer11::drawLines2D()
|
void Renderer11::drawLines2D()
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
#include "fullblock_switch.h"
|
#include "fullblock_switch.h"
|
||||||
#include "itemdata/creature_info.h"
|
#include "itemdata/creature_info.h"
|
||||||
#include <Objects/Effects/effect_objects.h>
|
#include <Objects/Effects/effect_objects.h>
|
||||||
|
#include "Game/rope.h"
|
||||||
|
|
||||||
|
using namespace TEN::Game::Rope;
|
||||||
using namespace TEN::Entities::Switches;
|
using namespace TEN::Entities::Switches;
|
||||||
|
|
||||||
OBJECT_INFO Objects[ID_NUMBER_OBJECTS];
|
OBJECT_INFO Objects[ID_NUMBER_OBJECTS];
|
||||||
|
|
|
@ -177,3 +177,88 @@ BoundingOrientedBox TO_DX_BBOX(PHD_3DPOS pos, BOUNDING_BOX* box)
|
||||||
BoundingOrientedBox(boxCentre, boxExtent, Vector4::UnitY).Transform(result, 1, rotation, Vector3(pos.xPos, pos.yPos, pos.zPos));
|
BoundingOrientedBox(boxCentre, boxExtent, Vector4::UnitY).Transform(result, 1, rotation, Vector3(pos.xPos, pos.yPos, pos.zPos));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__int64 FP_Mul(__int64 a, __int64 b)
|
||||||
|
{
|
||||||
|
return (int)((((__int64)a * (__int64)b)) >> FP_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
__int64 FP_Div(__int64 a, __int64 b)
|
||||||
|
{
|
||||||
|
return (int)(((a) / (b >> 8)) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FP_VectorMul(PHD_VECTOR* v, int scale, PHD_VECTOR* result)
|
||||||
|
{
|
||||||
|
result->x = FP_FromFixed(v->x * scale);
|
||||||
|
result->y = FP_FromFixed(v->y * scale);
|
||||||
|
result->z = FP_FromFixed(v->z * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FP_DotProduct(PHD_VECTOR* a, PHD_VECTOR* b)
|
||||||
|
{
|
||||||
|
return ((a->x * b->x) + (a->y * b->y) + (a->z * b->z)) >> W2V_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FP_CrossProduct(PHD_VECTOR* a, PHD_VECTOR* b, PHD_VECTOR* result)
|
||||||
|
{
|
||||||
|
result->x = ((a->y * b->z) - (a->z * b->y)) >> W2V_SHIFT;
|
||||||
|
result->y = ((a->z * b->x) - (a->x * b->z)) >> W2V_SHIFT;
|
||||||
|
result->z = ((a->x * b->y) - (a->y * b->x)) >> W2V_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FP_GetMatrixAngles(MATRIX3D* m, short* angles)
|
||||||
|
{
|
||||||
|
short yaw = phd_atan(m->m22, m->m02);
|
||||||
|
short pitch = phd_atan(sqrt((m->m22 * m->m22) + (m->m02 * m->m02)), m->m12);
|
||||||
|
|
||||||
|
int sy = phd_sin(yaw);
|
||||||
|
int cy = phd_cos(yaw);
|
||||||
|
short roll = phd_atan(((cy * m->m00) - (sy * m->m20)), ((sy * m->m21) - (cy * m->m01)));
|
||||||
|
|
||||||
|
if (((m->m12 >= 0) && pitch > 0)
|
||||||
|
|| ((m->m12 < 0) && pitch < 0))
|
||||||
|
pitch = -pitch;
|
||||||
|
|
||||||
|
angles[0] = pitch;
|
||||||
|
angles[1] = yaw;
|
||||||
|
angles[2] = roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
__int64 FP_ToFixed(__int64 value)
|
||||||
|
{
|
||||||
|
return (value << FP_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
__int64 FP_FromFixed(__int64 value)
|
||||||
|
{
|
||||||
|
return (value >> FP_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
PHD_VECTOR* FP_Normalise(PHD_VECTOR* v)
|
||||||
|
{
|
||||||
|
long a = v->x >> FP_SHIFT;
|
||||||
|
long b = v->y >> FP_SHIFT;
|
||||||
|
long c = v->z >> FP_SHIFT;
|
||||||
|
|
||||||
|
if ((a == 0) && (b == 0) && (c == 0))
|
||||||
|
return v;
|
||||||
|
|
||||||
|
a = a * a;
|
||||||
|
b = b * b;
|
||||||
|
c = c * c;
|
||||||
|
long d = (a + b + c);
|
||||||
|
long e = sqrt(abs(d));
|
||||||
|
|
||||||
|
e <<= FP_SHIFT;
|
||||||
|
|
||||||
|
long mod = FP_Div(FP_ONE << 8, e);
|
||||||
|
mod >>= 8;
|
||||||
|
|
||||||
|
v->x = FP_Mul(v->x, mod);
|
||||||
|
v->y = FP_Mul(v->y, mod);
|
||||||
|
v->z = FP_Mul(v->z, mod);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
|
@ -56,3 +56,21 @@ void phd_RotBoundingBoxNoPersp(PHD_3DPOS* pos, BOUNDING_BOX* bounds, BOUNDING_BO
|
||||||
|
|
||||||
void InterpolateAngle(short angle, short* rotation, short* outAngle, int shift);
|
void InterpolateAngle(short angle, short* rotation, short* outAngle, int shift);
|
||||||
void GetMatrixFromTrAngle(Matrix* matrix, short* frameptr, int index);
|
void GetMatrixFromTrAngle(Matrix* matrix, short* frameptr, int index);
|
||||||
|
|
||||||
|
constexpr auto FP_SHIFT = 16;
|
||||||
|
constexpr auto FP_ONE = (1 << FP_SHIFT);
|
||||||
|
constexpr auto W2V_SHIFT = 14;
|
||||||
|
|
||||||
|
void FP_VectorMul(PHD_VECTOR* v, int scale, PHD_VECTOR* result);
|
||||||
|
__int64 FP_Mul(__int64 a, __int64 b);
|
||||||
|
__int64 FP_Div(__int64 a, __int64 b);
|
||||||
|
int FP_DotProduct(PHD_VECTOR* a, PHD_VECTOR* b);
|
||||||
|
void FP_CrossProduct(PHD_VECTOR* a, PHD_VECTOR* b, PHD_VECTOR* n);
|
||||||
|
void FP_GetMatrixAngles(MATRIX3D* m, short* angles);
|
||||||
|
__int64 FP_ToFixed(__int64 value);
|
||||||
|
__int64 FP_FromFixed(__int64 value);
|
||||||
|
PHD_VECTOR* FP_Normalise(PHD_VECTOR* v);
|
||||||
|
|
||||||
|
|
||||||
|
#define MULFP(a,b) (int)((((__int64)a*(__int64)b))>>16)
|
||||||
|
#define DIVFP(a,b) (int)(((a)/(b>>8))<<8)
|
Loading…
Add table
Add a link
Reference in a new issue