mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-12 21:47:03 +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"
|
||||
#endif
|
||||
|
||||
#include "Game/rope.h"
|
||||
|
||||
using namespace TEN::Game::Rope;
|
||||
using std::function;
|
||||
using TEN::Renderer::g_Renderer;
|
||||
using namespace TEN::Control::Volumes;
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#include "collide.h"
|
||||
#include "items.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.*/
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,51 +2,57 @@
|
|||
|
||||
#include "collide.h"
|
||||
|
||||
struct ROPE_STRUCT
|
||||
namespace TEN::Game::Rope
|
||||
{
|
||||
PHD_VECTOR segment[24]; // size=288, offset=0
|
||||
PHD_VECTOR velocity[24]; // size=288, offset=288
|
||||
PHD_VECTOR normalisedSegment[24]; // size=288, offset=576
|
||||
PHD_VECTOR meshSegment[24]; // size=288, offset=864
|
||||
PHD_VECTOR position; // size=12, offset=1152
|
||||
PHD_VECTOR Unknown[24];
|
||||
int segmentLength; // size=0, offset=1164
|
||||
short active; // size=0, offset=1168
|
||||
short coiled; // size=0, offset=1170
|
||||
};
|
||||
struct ROPE_STRUCT
|
||||
{
|
||||
PHD_VECTOR segment[24]; // size=288, offset=0
|
||||
PHD_VECTOR velocity[24]; // size=288, offset=288
|
||||
PHD_VECTOR normalisedSegment[24]; // size=288, offset=576
|
||||
PHD_VECTOR meshSegment[24]; // size=288, offset=864
|
||||
PHD_VECTOR position; // size=12, offset=1152
|
||||
PHD_VECTOR coords[24];
|
||||
int segmentLength; // size=0, offset=1164
|
||||
short active; // size=0, offset=1168
|
||||
short coiled; // size=0, offset=1170
|
||||
};
|
||||
|
||||
struct PENDULUM
|
||||
{
|
||||
PHD_VECTOR Position; // size=12, offset=0
|
||||
PHD_VECTOR Velocity; // size=12, offset=12
|
||||
int node; // size=0, offset=24
|
||||
ROPE_STRUCT* Rope; // size=1172, offset=28
|
||||
};
|
||||
struct PENDULUM
|
||||
{
|
||||
PHD_VECTOR Position; // size=12, offset=0
|
||||
PHD_VECTOR Velocity; // size=12, offset=12
|
||||
int node; // size=0, offset=24
|
||||
ROPE_STRUCT* Rope; // size=1172, offset=28
|
||||
};
|
||||
|
||||
extern PENDULUM CurrentPendulum;
|
||||
extern ROPE_STRUCT Ropes[12];
|
||||
extern int NumRopes;
|
||||
constexpr auto ROPE_SEGMENTS = 24;
|
||||
constexpr auto ROPE_WIDTH = 24;
|
||||
|
||||
void InitialiseRope(short itemNumber);
|
||||
void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int length, ITEM_INFO* item);
|
||||
PHD_VECTOR* NormaliseRopeVector(PHD_VECTOR* vec);
|
||||
void _0x0046D130(ROPE_STRUCT* rope, int segmentFrame, int* x, int* y, int* z);
|
||||
int DotProduct(PHD_VECTOR* u, PHD_VECTOR* v);
|
||||
void ScaleVector(PHD_VECTOR* src, int c, PHD_VECTOR* dest);
|
||||
void CrossProduct(PHD_VECTOR* u, PHD_VECTOR* v, PHD_VECTOR* dest);
|
||||
void _0x0046D420(int* array, short* angle);
|
||||
void RopeControl(short itemNumber);
|
||||
void RopeCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll);
|
||||
void RopeDynamics(ROPE_STRUCT* rope);
|
||||
int _0x0046D200(ROPE_STRUCT* rope, int x, int y, int z, int value);
|
||||
void ApplyVelocityToRope(int node, short angle, short n);
|
||||
void SetPendulumVelocity(int x, int y, int z);
|
||||
void _0x0046E1C0(ROPE_STRUCT* rope, int node);
|
||||
void _0x0046E080(ROPE_STRUCT* rope, PENDULUM* pendulumPointer, PHD_VECTOR* ropeVelocity, PHD_VECTOR* pendulumVelocity, int value);
|
||||
void _0x0046DF00(PHD_VECTOR* segment, PHD_VECTOR* nextSegment, PHD_VECTOR* velocity, PHD_VECTOR* nextVelocity, int length);
|
||||
void UpdateRopeSwing(ITEM_INFO* item);
|
||||
void JumpOffRope(ITEM_INFO* item);
|
||||
void FallFromRope(ITEM_INFO* item);
|
||||
void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll);
|
||||
void DelAlignLaraToRope(ITEM_INFO* item);
|
||||
extern PENDULUM CurrentPendulum;
|
||||
extern PENDULUM AlternatePendulum;
|
||||
extern std::vector<ROPE_STRUCT> Ropes;
|
||||
extern int RopeSwing;
|
||||
|
||||
void InitialiseRope(short itemNumber);
|
||||
void PrepareRope(ROPE_STRUCT* rope, PHD_VECTOR* pos1, PHD_VECTOR* pos2, int length, ITEM_INFO* item);
|
||||
PHD_VECTOR* NormaliseRopeVector(PHD_VECTOR* vec);
|
||||
void GetRopePos(ROPE_STRUCT* rope, int segmentFrame, int* x, int* y, int* z);
|
||||
int DotProduct(PHD_VECTOR* u, PHD_VECTOR* v);
|
||||
void ScaleVector(PHD_VECTOR* src, int c, PHD_VECTOR* dest);
|
||||
void CrossProduct(PHD_VECTOR* u, PHD_VECTOR* v, PHD_VECTOR* dest);
|
||||
void phd_GetMatrixAngles(int* array, short* angle);
|
||||
void RopeControl(short itemNumber);
|
||||
void RopeCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll);
|
||||
void RopeDynamics(ROPE_STRUCT* rope);
|
||||
int _0x0046D200(ROPE_STRUCT* rope, int x, int y, int z, int value);
|
||||
void ApplyVelocityToRope(int node, short angle, short n);
|
||||
void SetPendulumVelocity(int x, int y, int z);
|
||||
void _0x0046E1C0(ROPE_STRUCT* rope, int node);
|
||||
void _0x0046E080(ROPE_STRUCT* rope, PENDULUM* pendulumPointer, PHD_VECTOR* ropeVelocity, PHD_VECTOR* pendulumVelocity, int value);
|
||||
void _0x0046DF00(PHD_VECTOR* segment, PHD_VECTOR* nextSegment, PHD_VECTOR* velocity, PHD_VECTOR* nextVelocity, int length);
|
||||
void UpdateRopeSwing(ITEM_INFO* item);
|
||||
void JumpOffRope(ITEM_INFO* item);
|
||||
void FallFromRope(ITEM_INFO* item);
|
||||
void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll);
|
||||
void DelAlignLaraToRope(ITEM_INFO* item);
|
||||
}
|
|
@ -32,6 +32,9 @@
|
|||
#include <Objects/Effects/tr4_locusts.h>
|
||||
#include <control\volume.h>
|
||||
#include "items.h"
|
||||
#include "Game/rope.h"
|
||||
|
||||
using namespace TEN::Game::Rope;
|
||||
|
||||
extern TEN::Renderer::RendererHUDBar *g_DashBar;
|
||||
extern TEN::Renderer::RendererHUDBar *g_SFXVolumeBar;
|
||||
|
@ -1960,121 +1963,43 @@ namespace TEN::Renderer
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// Original algorithm:
|
||||
// 1) Transform segment coordinates from 3D to 2D + depth
|
||||
// 2) Get dx, dy and the segment length
|
||||
// 3) Get sine and cosine from dx / length and dy / length
|
||||
// 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
|
||||
Matrix world = Matrix::CreateTranslation(
|
||||
rope->position.x,
|
||||
rope->position.y,
|
||||
rope->position.z
|
||||
);
|
||||
|
||||
// Tranform rope points
|
||||
Vector3 projected[24];
|
||||
Matrix world = Matrix::Identity;
|
||||
Vector3 absolute[24];
|
||||
|
||||
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,
|
||||
rope->position.y + rope->segment[i].y / 65536.0f,
|
||||
rope->position.z + rope->segment[i].z / 65536.0f);
|
||||
PHD_VECTOR* s = &rope->meshSegment[n];
|
||||
Vector3 t;
|
||||
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
|
||||
// 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)
|
||||
for (int n = 0; n < ROPE_SEGMENTS - 1; n++)
|
||||
{
|
||||
s = -dy / length;
|
||||
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;
|
||||
addLine3D(absolute[n], absolute[n + 1], Vector4::One);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Renderer11::drawLines2D()
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#include "fullblock_switch.h"
|
||||
#include "itemdata/creature_info.h"
|
||||
#include <Objects/Effects/effect_objects.h>
|
||||
#include "Game/rope.h"
|
||||
|
||||
using namespace TEN::Game::Rope;
|
||||
using namespace TEN::Entities::Switches;
|
||||
|
||||
OBJECT_INFO Objects[ID_NUMBER_OBJECTS];
|
||||
|
|
|
@ -176,4 +176,89 @@ BoundingOrientedBox TO_DX_BBOX(PHD_3DPOS pos, BOUNDING_BOX* box)
|
|||
BoundingOrientedBox result;
|
||||
BoundingOrientedBox(boxCentre, boxExtent, Vector4::UnitY).Transform(result, 1, rotation, Vector3(pos.xPos, pos.yPos, pos.zPos));
|
||||
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;
|
||||
}
|
|
@ -55,4 +55,22 @@ void phd_GetVectorAngles(int x, int y, int z, short* angles);
|
|||
void phd_RotBoundingBoxNoPersp(PHD_3DPOS* pos, BOUNDING_BOX* bounds, BOUNDING_BOX* tbounds);
|
||||
|
||||
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