New level format: meshes

This commit is contained in:
MontyTRC89 2020-07-03 07:05:33 +02:00
parent eaf358f6ae
commit 7ff7397fa7
40 changed files with 368 additions and 2064 deletions

View file

@ -36,14 +36,14 @@ typedef enum ZoneType
ZONE_APE, // only 2 click climb
};
typedef struct OBJECT_BONES
typedef struct OBJECT_Bones
{
short bone0;
short bone1;
short bone2;
short bone3;
OBJECT_BONES()
OBJECT_Bones()
{
this->bone0 = 0;
this->bone1 = 0;
@ -51,7 +51,7 @@ typedef struct OBJECT_BONES
this->bone3 = 0;
}
OBJECT_BONES(short all)
OBJECT_Bones(short all)
{
this->bone0 = all;
this->bone1 = all;
@ -59,7 +59,7 @@ typedef struct OBJECT_BONES
this->bone3 = all;
}
OBJECT_BONES(short angleY, short angleX)
OBJECT_Bones(short angleY, short angleX)
{
this->bone0 = angleY;
this->bone1 = angleX;
@ -67,7 +67,7 @@ typedef struct OBJECT_BONES
this->bone3 = angleX;
}
OBJECT_BONES(short angleY, short angleX, bool total)
OBJECT_Bones(short angleY, short angleX, bool total)
{
this->bone0 = angleY;
this->bone1 = angleX;

View file

@ -2625,7 +2625,7 @@ int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOr
hitPos->z = collidedPoint.z - itemOrStaticPos->zPos;
// Now in the case of items we need to test single spheres
short *meshPtr = NULL;
MESH* meshPtr = NULL;
int bit = 0;
int sp = -2;
float minDistance = SECTOR(1024);
@ -2651,7 +2651,7 @@ int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOr
if (obj->nmeshes <= 0)
return 0;
meshPtr = Meshes[obj->meshIndex];
meshPtr = &Meshes[obj->meshIndex];
for (int i = 0; i < obj->nmeshes; i++)
{
@ -2674,7 +2674,7 @@ int DoRayBox(GAME_VECTOR *start, GAME_VECTOR *end, short *box, PHD_3DPOS *itemOr
if (newDist < minDistance)
{
minDistance = newDist;
meshPtr = Meshes[obj->meshIndex + i];
meshPtr = &Meshes[obj->meshIndex + i];
bit = 1 << i;
sp = i;
}
@ -3070,7 +3070,7 @@ int ExplodeItemNode(ITEM_INFO *item, int Node, int NoXZVel, int bits)
GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity);
ShatterItem.yRot = item->pos.yRot;
ShatterItem.bit = 1 << Node;
ShatterItem.meshp = Meshes[Objects[item->objectNumber].meshIndex + Node];
ShatterItem.meshp = &Meshes[Objects[item->objectNumber].meshIndex + Node];
ShatterItem.sphere.x = CreatureSpheres[Node].x;
ShatterItem.sphere.y = CreatureSpheres[Node].y;
ShatterItem.sphere.z = CreatureSpheres[Node].z;

View file

@ -24,12 +24,12 @@ DebrisFragment* GetFreeDebrisFragment()
void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num,short roomNumber,int noZXVel)
{
short* meshPtr = nullptr;
MESH* meshPtr = nullptr;
RendererMesh* fragmentsMesh;
short yRot = 0;
Vector3 pos;
if (mesh) {
meshPtr = Meshes[StaticObjects[mesh->staticNumber].meshNumber];
meshPtr = &Meshes[StaticObjects[mesh->staticNumber].meshNumber];
yRot = mesh->yRot;
pos = Vector3(mesh->x, mesh->y, mesh->z);
}
@ -38,7 +38,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num,short roomNumber
yRot = item->yRot;
pos = Vector3(item->sphere.x, item->sphere.y, item->sphere.z);
}
fragmentsMesh = g_Renderer.getMeshFromMeshPtr(reinterpret_cast<unsigned int>(meshPtr));
fragmentsMesh = g_Renderer.getMesh(0);
for (int bucket = RENDERER_BUCKET_SOLID; bucket <= RENDERER_BUCKET_TRANSPARENT; bucket++) {
RendererBucket renderBucket = fragmentsMesh->Buckets[bucket];
vector<RendererVertex>* meshVertices = &renderBucket.Vertices;

View file

@ -1,6 +1,8 @@
#pragma once
#include "sphere.h"
#include "Renderer11.h"
#include <sphere.h>
#include <Renderer11.h>
#include <newtypes.h>
#include <level.h>
#define MAX_DEBRIS 256
@ -25,7 +27,7 @@ typedef struct SHATTER_ITEM
{
SPHERE sphere;
ITEM_LIGHT* il;
short* meshp;
MESH* meshp;
int bit;
short yRot;
short flags;

View file

@ -380,12 +380,10 @@ void ExplosionFX(ITEM_INFO* item)//39694(<), 39B94(<) (F)
void SwapCrowbar(ITEM_INFO* item)//39638(<), 39B38(<) (F)
{
short* tmp = Meshes[Objects[ID_LARA].meshIndex + LM_RHAND];
if (Lara.meshPtrs[LM_RHAND] == tmp)
Lara.meshPtrs[LM_RHAND] = Meshes[Objects[ID_LARA_CROWBAR_ANIM].meshIndex + LM_RHAND];
if (Lara.meshPtrs[LM_RHAND] == Objects[ID_LARA].meshIndex + LM_RHAND)
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_CROWBAR_ANIM].meshIndex + LM_RHAND;
else
Lara.meshPtrs[LM_RHAND] = tmp;
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA].meshIndex + LM_RHAND;
}
void ActivateKey(ITEM_INFO* item)//39624(<), 39B24(<) (F)

View file

@ -110,7 +110,8 @@ void DoFlameTorch() // (F) (D)
}
else if (Lara.leftArm.frameNumber == 12)
{
LARA_MESHES(ID_LARA, LM_LHAND);
//LARA_MESHES(ID_LARA, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
CreateFlare(ID_BURNING_TORCH_ITEM, 1);
}
}
@ -130,7 +131,8 @@ void DoFlameTorch() // (F) (D)
}
else if (Lara.leftArm.frameNumber == 36)
{
LARA_MESHES(ID_LARA, LM_LHAND);
//LARA_MESHES(ID_LARA, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
CreateFlare(ID_BURNING_TORCH_ITEM, 0);
}
break;
@ -187,7 +189,9 @@ void GetFlameTorch() // (F) (D)
Lara.leftArm.lock = false;
Lara.leftArm.frameNumber = 0;
Lara.leftArm.frameBase = Anims[Lara.leftArm.animNumber].framePtr;
LARA_MESHES(ID_LARA_TORCH_ANIM, LM_LHAND);
//LARA_MESHES(ID_LARA_TORCH_ANIM, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_TORCH_ANIM].meshIndex + LM_LHAND;
}
void TorchControl(short itemNumber) // (F) (D)

View file

@ -100,47 +100,47 @@ void HairControl(int cutscene, int ponytail, short* framePtr)
}
// Get Lara's spheres in absolute coords, for head, torso, hips and upper arms
short* objptr = Lara.meshPtrs[LM_HIPS];
PHD_VECTOR pos = { objptr[0], objptr[1], objptr[2] };
MESH* objptr = &Meshes[Lara.meshPtrs[LM_HIPS]];
PHD_VECTOR pos = { (int)objptr->sphere.Center.x, (int)objptr->sphere.Center.y, (int)objptr->sphere.Center.z };
GetLaraJointPosition(&pos, LM_HIPS);
sphere[0].x = pos.x;
sphere[0].y = pos.y;
sphere[0].z = pos.z;
sphere[0].r = (int) * (objptr + 3);
sphere[0].r = (int)objptr->sphere.Radius;
objptr = Lara.meshPtrs[LM_TORSO];
pos = { objptr[0], objptr[1], objptr[2] };
objptr = &Meshes[Lara.meshPtrs[LM_TORSO]];
pos = { (int)objptr->sphere.Center.x, (int)objptr->sphere.Center.y, (int)objptr->sphere.Center.z };
GetLaraJointPosition(&pos, LM_TORSO);
sphere[1].x = pos.x;
sphere[1].y = pos.y;
sphere[1].z = pos.z;
sphere[1].r = (int) * (objptr + 3);
sphere[1].r = (int)objptr->sphere.Radius;
if (youngLara)
sphere[1].r = sphere[1].r - ((sphere[1].r >> 2) + (sphere[1].r >> 3));
objptr = Lara.meshPtrs[LM_HEAD];
pos = { objptr[0], objptr[1], objptr[2] };
objptr = &Meshes[Lara.meshPtrs[LM_HEAD]];
pos = { (int)objptr->sphere.Center.x, (int)objptr->sphere.Center.y, (int)objptr->sphere.Center.z };
GetLaraJointPosition(&pos, LM_HEAD);
sphere[2].x = pos.x;
sphere[2].y = pos.y;
sphere[2].z = pos.z;
sphere[2].r = (int) * (objptr + 3);
sphere[2].r = (int)objptr->sphere.Radius;
objptr = Lara.meshPtrs[LM_RINARM];
pos = { objptr[0], objptr[1], objptr[2] };
objptr = &Meshes[Lara.meshPtrs[LM_RINARM]];
pos = { (int)objptr->sphere.Center.x, (int)objptr->sphere.Center.y, (int)objptr->sphere.Center.z };
GetLaraJointPosition(&pos, LM_RINARM);
sphere[3].x = pos.x;
sphere[3].y = pos.y;
sphere[3].z = pos.z;
sphere[3].r = (int) * (objptr + 3) * 3 / 2;
sphere[3].r = (int)objptr->sphere.Radius * 3 / 2;
objptr = Lara.meshPtrs[LM_LINARM];
pos = { objptr[0], objptr[1], objptr[2] };
objptr = &Meshes[Lara.meshPtrs[LM_LINARM]];
pos = { (int)objptr->sphere.Center.x, (int)objptr->sphere.Center.y, (int)objptr->sphere.Center.z };
GetLaraJointPosition(&pos, LM_LINARM);
sphere[4].x = pos.x;
sphere[4].y = pos.y;
sphere[4].z = pos.z;
sphere[4].r = (int) * (objptr + 3) * 3 / 2;
sphere[4].r = (int)objptr->sphere.Radius * 3 / 2;
if (youngLara)
{

View file

@ -1511,13 +1511,15 @@ void undraw_shotgun(int weapon)
void undraw_shotgun_meshes(int weapon)
{
Lara.backGun = WeaponObject(weapon);
LARA_MESHES(ID_LARA, LM_RHAND);
//LARA_MESHES(ID_LARA, LM_RHAND);
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
}
void draw_shotgun_meshes(int weaponType)
{
Lara.backGun = WEAPON_NONE;
LARA_MESHES(WeaponObjectMesh(weaponType), LM_RHAND);
//LARA_MESHES(WeaponObjectMesh(weaponType), LM_RHAND);
Lara.meshPtrs[LM_RHAND] = Objects[WeaponObjectMesh(weaponType)].meshIndex + LM_RHAND;
}
void DoCrossbowDamage(ITEM_INFO* item1, ITEM_INFO* item2, signed int search)

View file

@ -351,7 +351,8 @@ void PistolHandler(int weaponType)
void undraw_pistol_mesh_right(int weaponType)
{
LARA_MESHES(ID_LARA, LM_RHAND);
//LARA_MESHES(ID_LARA, LM_RHAND);
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
switch (weaponType)
{
@ -372,7 +373,8 @@ void undraw_pistol_mesh_left(int weaponType)
{
if (weaponType != WEAPON_REVOLVER)
{
LARA_MESHES(ID_LARA, LM_LHAND);
//LARA_MESHES(ID_LARA, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
switch (weaponType)
{
@ -390,9 +392,11 @@ void draw_pistol_meshes(int weaponType)
{
Lara.holster = ID_LARA_HOLSTERS;
LARA_MESHES(WeaponObjectMesh(weaponType), LM_RHAND);
//LARA_MESHES(WeaponObjectMesh(weaponType), LM_RHAND);
Lara.meshPtrs[LM_RHAND] = Objects[WeaponObjectMesh(weaponType)].meshIndex + LM_RHAND;
if (weaponType != WEAPON_REVOLVER)
LARA_MESHES(WeaponObjectMesh(weaponType), LM_LHAND);
//LARA_MESHES(WeaponObjectMesh(weaponType), LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[WeaponObjectMesh(weaponType)].meshIndex + LM_LHAND;
}
void ready_pistols(int weaponType)

View file

@ -835,7 +835,7 @@ typedef struct LaraInfo
PHD_VECTOR lastPos;
FX_INFO* spazEffect;
int meshEffects;
short* meshPtrs[NUM_LARA_MESHES];
int meshPtrs[NUM_LARA_MESHES];
ITEM_INFO* target;
short targetAngles[2];
short turnRate;

View file

@ -310,7 +310,7 @@ void AimWeapon(WEAPON_INFO* winfo, LARA_ARM* arm) // (F) (D)
rotX -= speed;
arm->xRot = rotX;
// TODO: set arm rotations to inherit rotations of parent bones. -Sezz
// TODO: set arm rotations to inherit rotations of parent Bones. -Sezz
arm->zRot = 0;
}
@ -472,7 +472,8 @@ void LaraGun() // (F) (D)
break;
case LG_UNDRAW_GUNS:
LARA_MESHES(ID_LARA, LM_HEAD);
//LARA_MESHES(ID_LARA, LM_HEAD);
Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD;
switch (Lara.gunType)
{
@ -504,9 +505,11 @@ void LaraGun() // (F) (D)
case LG_READY:
if (!(TrInput & IN_ACTION))
LARA_MESHES(ID_LARA, LM_HEAD);
//LARA_MESHES(ID_LARA, LM_HEAD);
Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD;
else
LARA_MESHES(ID_LARA_SCREAM, LM_HEAD);
//LARA_MESHES(ID_LARA_SCREAM, LM_HEAD);
Lara.meshPtrs[LM_HEAD] = Objects[ID_LARA_SCREAM].meshIndex + LM_HEAD;
if (Camera.type != CINEMATIC_CAMERA && Camera.type != LOOK_CAMERA && Camera.type != HEAVY_CAMERA)
Camera.type = COMBAT_CAMERA;
@ -580,7 +583,7 @@ void LaraGun() // (F) (D)
case LG_HANDS_BUSY:
if (Lara.gunType == WEAPON_FLARE)
{
if (CHECK_LARA_MESHES(ID_LARA_FLARE_ANIM, LM_LHAND))
if (Lara.meshPtrs[LM_LHAND] == Objects[ID_LARA_FLARE_ANIM].meshIndex + LM_LHAND /*CHECK_LARA_MESHES(ID_LARA_FLARE_ANIM, LM_LHAND)*/)
{
#if 0
Lara.flareControlLeft = (Lara.Vehicle != NO_ITEM || CheckForHoldingState(LaraItem->currentAnimState));

View file

@ -104,12 +104,14 @@ void ready_flare() // (F) (D)
void undraw_flare_meshes() // (F) (D)
{
LARA_MESHES(ID_LARA, LM_LHAND);
//LARA_MESHES(ID_LARA, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
}
void draw_flare_meshes() // (F) (D)
{
LARA_MESHES(ID_LARA_FLARE_ANIM, LM_LHAND);
//LARA_MESHES(ID_LARA_FLARE_ANIM, LM_LHAND);
Lara.meshPtrs[LM_LHAND] = Objects[ID_LARA_FLARE_ANIM].meshIndex + LM_LHAND;
}
void undraw_flare() // (F) (D)

View file

@ -742,8 +742,9 @@ void LaraInitialiseMeshes() // (AF) (D)
{
for (int i = 0; i < NUM_LARA_MESHES; i++)
{
MESHES(ID_LARA, i) = MESHES(ID_LARA_SKIN, i);
LARA_MESHES(ID_LARA, i);
//Meshes[i] = Meshes[MESHES(ID_LARA_SKIN, i)];
//LARA_MESHES(ID_LARA, MESHES(ID_LARA_SKIN, i));
Lara.meshPtrs[i] = Objects[ID_LARA_SKIN].meshIndex + i;
}
/* Hardcoded code */

View file

@ -1,34 +1,6 @@
#pragma once
#include <framework.h>
typedef struct tr5_room_layer
{
unsigned int NumLayerVertices; // Number of vertices in this layer (4 bytes)
unsigned short UnknownL1;
unsigned short NumLayerRectangles; // Number of rectangles in this layer (2 bytes)
unsigned short NumLayerTriangles; // Number of triangles in this layer (2 bytes)
unsigned short UnknownL2;
unsigned short Filler; // Always 0
unsigned short Filler2; // Always 0
/// The following 6 floats define the bounding box for the layer
float LayerBoundingBoxX1;
float LayerBoundingBoxY1;
float LayerBoundingBoxZ1;
float LayerBoundingBoxX2;
float LayerBoundingBoxY2;
float LayerBoundingBoxZ2;
unsigned int Filler3; // Always 0 (4 bytes)
void* VerticesOffset;
void* PolyOffset;
void* PolyOffset2;
};
typedef struct tr5_vertex
{
float x;
float y;
float z;
};
#include <newtypes.h>
struct ROOM_VERTEX
{
@ -37,6 +9,7 @@ struct ROOM_VERTEX
Vector2 textureCoordinates;
Vector3 color;
int effects;
int index;
};
struct ROOM_DOOR
@ -46,20 +19,6 @@ struct ROOM_DOOR
Vector3 vertices[4];
};
typedef struct tr4_mesh_face3 // 10 bytes
{
short Vertices[3];
short Texture;
short Effects; // TR4-5 ONLY: alpha blending and environment mapping strength
};
typedef struct tr4_mesh_face4 // 12 bytes
{
short Vertices[4];
short Texture;
short Effects;
};
struct POLYGON
{
int shape;
@ -67,24 +26,6 @@ struct POLYGON
int texture;
};
struct BUCKET
{
int texture;
byte blendMode;
bool animated;
std::vector<int> indices;
};
typedef struct tr_room_sector // 8 bytes
{
unsigned short FDindex; // Index into FloorData[]
unsigned short BoxIndex; // Index into Boxes[] (-1 if none)
unsigned char RoomBelow; // 255 is none
signed char Floor; // Absolute height of floor
unsigned char RoomAbove; // 255 if none
signed char Ceiling; // Absolute height of ceiling
};
typedef struct ROOM_LIGHT
{
float x, y, z; // Position of light, in world coordinates
@ -157,7 +98,7 @@ struct SECTOR_COLLISION_INFO
SECTOR_PLANE planes[2];
};
typedef struct FLOOR_INFO
struct FLOOR_INFO
{
int index;
int box;
@ -171,7 +112,7 @@ typedef struct FLOOR_INFO
SECTOR_COLLISION_INFO ceilingCollision;
};
typedef enum RoomEnumFlag
enum RoomEnumFlag
{
ENV_FLAG_WATER = 0x0001,
ENV_FLAG_SWAMP = 0x0004,
@ -185,7 +126,7 @@ typedef enum RoomEnumFlag
ENV_FLAG_UNKNOWN3 = 0x0400
};
typedef struct ROOM_INFO
struct ROOM_INFO
{
int x;
int y;
@ -211,7 +152,7 @@ typedef struct ROOM_INFO
bool boundActive;
};
typedef struct ANIM_STRUCT
struct ANIM_STRUCT
{
short* framePtr;
short interpolation;

View file

@ -215,9 +215,6 @@ void SaveGame::saveLara(int arg1, int arg2)
LaraInfo lara;
memcpy(&lara, &Lara, sizeof(Lara));
for (int i = 0; i < 15; i++)
lara.meshPtrs[i] = (short*)((char*)lara.meshPtrs[i] - (ptrdiff_t)MeshBase);
lara.leftArm.frameBase = (short*)((char *)lara.leftArm.frameBase - (ptrdiff_t)Objects[ID_LARA].frameBase);
lara.rightArm.frameBase = (short*)((char *)lara.rightArm.frameBase - (ptrdiff_t)Objects[ID_LARA].frameBase);
lara.generalPtr = (char *)lara.generalPtr - (ptrdiff_t)malloc_buffer;
@ -512,11 +509,6 @@ bool SaveGame::readLara()
memcpy(&Lara, lara, sizeof(LaraInfo));
free(buffer);
for (int i = 0; i < NUM_LARA_MESHES; i++)
{
Lara.meshPtrs[i] = AddPtr(Lara.meshPtrs[i], short, MeshBase);
}
Lara.leftArm.frameBase = AddPtr(Lara.leftArm.frameBase, short, Objects[ID_LARA].frameBase);
Lara.rightArm.frameBase = AddPtr(Lara.rightArm.frameBase, short, Objects[ID_LARA].frameBase);

View file

@ -619,7 +619,7 @@ typedef enum sound_effects
SFX_TR1_BULLET_HITTING_LARA = 500,
SFX_TR1_LARA_HEH_STARTING_TO_PULL_BLOCK = 501,
SFX_TR1_LARA_TREADING_WATER = 502,
SFX_TR1_LARA_S_BONES_BREAKING_DYING = 503,
SFX_TR1_LARA_S_Bones_BREAKING_DYING = 503,
SFX_TR1_LEDGE_GRAB_BY_LARA = 504,
SFX_TR1_LARA_OOMPH_HITTING_WALL_AFTER_GRABBING_LEDGE = 505,
SFX_TR1_FOOTSTEP_LEDGE_SHIMMY_BY_LARA = 506,
@ -877,7 +877,7 @@ typedef enum sound_effects
SFX_TR2_BULLET_HITTING_LARA = 756,
SFX_TR2_LARA_HEH_PULLING_UP = 757,
SFX_TR2_LARA_TREADING_WATER1 = 758,
SFX_TR2_LARA_S_BONES_BREAKING_DYING = 759,
SFX_TR2_LARA_S_Bones_BREAKING_DYING = 759,
SFX_TR2_LEDGE_GRAB_BY_LARA = 760,
SFX_TR2_LARA_OOMPH_HITTING_WALL_AFTER_GRABBING_LEDGE = 761,
SFX_TR2_FOOTSTEP_LEDGE_SHIMMY_BY_LARA = 762,

View file

@ -176,7 +176,7 @@ void BubblesEffect4(short fxNum, short xVel, short yVel, short zVel)
void BubblesShatterFunction(FX_INFO* fx, int param1, int param2)
{
ShatterItem.yRot = fx->pos.yRot;
ShatterItem.meshp = Meshes[fx->frameNumber];
ShatterItem.meshp = &Meshes[fx->frameNumber];
ShatterItem.sphere.x = fx->pos.xPos;
ShatterItem.sphere.y = fx->pos.yPos;
ShatterItem.sphere.z = fx->pos.zPos;

View file

@ -134,7 +134,7 @@ static void createExplosion(ITEM_INFO* item)
static void createDragonBone(short front_number)
{
/* Create the bones of the dragon */
/* Create the Bones of the dragon */
short bone_back, bone_front;
ITEM_INFO* back_dragon, *front_dragon, *item;
@ -239,7 +239,8 @@ void DragonCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
Lara.gunStatus = LG_HANDS_BUSY;
Lara.hitDirection = -1;
LARA_MESHES(ID_LARA_EXTRA_ANIMS, LM_RHAND);
//LARA_MESHES(ID_LARA_EXTRA_ANIMS, LM_RHAND);
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_EXTRA_ANIMS].meshIndex + LM_RHAND;
/* Do cinematic camera */
Camera.type = CINEMATIC_CAMERA;

View file

@ -247,7 +247,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->savePosition = true;
//Bones[obj->boneIndex + 5*4] |= (ROT_X | ROT_Y);
//Bones[obj->boneIndex + 14*4] |= (ROT_X | ROT_Y);
// TODO: get the correct torso and head bones value and assign ROT_X and ROT_Y to it !
// TODO: get the correct torso and head Bones value and assign ROT_X and ROT_Y to it !
}
obj = &Objects[ID_WORKER_MACHINEGUN];
@ -267,7 +267,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->savePosition = true;
//Bones[obj->boneIndex + 5*4] |= (ROT_X | ROT_Y);
//Bones[obj->boneIndex + 14*4] |= (ROT_X | ROT_Y);
// TODO: get the correct torso and head bones value and assign ROT_X and ROT_Y to it !
// TODO: get the correct torso and head Bones value and assign ROT_X and ROT_Y to it !
}
obj = &Objects[ID_SMALL_SPIDER];
@ -377,7 +377,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->savePosition = true;
//Bones[obj->boneIndex + 8 * 4] |= (ROT_X | ROT_Y);
//Bones[obj->boneIndex + 0 * 4] |= (ROT_X | ROT_Y);
// TODO: find the correct for bones (knifethrower).
// TODO: find the correct for Bones (knifethrower).
}
obj = &Objects[ID_KNIFETHROWER_KNIFE];
@ -505,7 +505,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->savePosition = true;
Bones[obj->boneIndex + 6 * 4] |= (ROT_X | ROT_Y);
Bones[obj->boneIndex + 16 * 4] |= (ROT_X | ROT_Y);
// TODO: bones value is not correct (shiva) !
// TODO: Bones value is not correct (shiva) !
// need the correct one.
}
@ -527,7 +527,7 @@ static void StartBaddy(ObjectInfo* obj)
obj->savePosition = true;
//Bones[obj->boneIndex + 6 * 4] |= (ROT_X | ROT_Y);
//Bones[obj->boneIndex + 12 * 4] |= (ROT_X | ROT_Y);
// TODO: get the correct id for bones ! (spear)
// TODO: get the correct id for Bones ! (spear)
}
obj = &Objects[ID_DRAGON_FRONT];

View file

@ -954,11 +954,11 @@ static void KayakUserInput(ITEM_INFO* kayak, ITEM_INFO* lara, KAYAK_INFO* kinfo)
/* --------------------- */
if ((lara->animNumber == Objects[ID_KAYAK_LARA_ANIMS].animIndex + 4) && (frame == 24) && (!(kinfo->Flags & 0x80)))
{
short* tmp;
tmp = Lara.meshPtrs[LM_RHAND];
/*MESH tmp = Meshes[Lara.meshPtrs[LM_RHAND]];
LARA_MESHES(ID_KAYAK_LARA_ANIMS, LM_RHAND);
Meshes[Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND] = tmp;
Meshes[Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND] = tmp;*/
Lara.meshPtrs[LM_RHAND] = Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND;
lara->meshBits &= ~LARA_LEG_BITS;
kinfo->Flags |= 0x80;
@ -968,11 +968,11 @@ static void KayakUserInput(ITEM_INFO* kayak, ITEM_INFO* lara, KAYAK_INFO* kinfo)
case KS_JUMPOUT:
if ((lara->animNumber == Objects[ID_KAYAK_LARA_ANIMS].animIndex + 14) && (frame == 27) && (kinfo->Flags & 0x80))
{
short* tmp;
tmp = Lara.meshPtrs[LM_RHAND];
/*MESH tmp = Meshes[Lara.meshPtrs[LM_RHAND]];
Lara.meshPtrs[LM_RHAND] = Meshes[Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND];
Meshes[Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND] = tmp;
LARA_MESHES(ID_KAYAK_LARA_ANIMS, LM_RHAND);
Meshes[Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND] = tmp;*/
Lara.meshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
lara->meshBits |= LARA_LEG_BITS;
kinfo->Flags &= ~0x80;

View file

@ -612,12 +612,11 @@ static void DoUserInput(ITEM_INFO* v, ITEM_INFO* l, CART_INFO* cart)
{
if ((l->frameNumber == GF2(ID_MINECART, 7, 0) + 20) && (cart->Flags & CF_MESH))
{
short* tmp;
tmp = Lara.meshPtrs[LM_RHAND];
/*MESH tmp = Meshes[Lara.meshPtrs[LM_RHAND]];
LARA_MESHES(ID_MINECART_LARA_ANIMS, LM_RHAND);
Meshes[Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND] = tmp;
Meshes[Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND] = tmp;*/
Lara.meshPtrs[LM_RHAND] = Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND;
cart->Flags &= ~CF_MESH;
}
@ -674,11 +673,9 @@ static void DoUserInput(ITEM_INFO* v, ITEM_INFO* l, CART_INFO* cart)
case CART_GETIN:
if ((l->animNumber == Objects[ID_MINECART_LARA_ANIMS].animIndex + 5) && (l->frameNumber == GF2(ID_MINECART, 5, 0) + 20) && (!cart->Flags & CF_MESH))
{
short* tmp;
MESH tmp = Meshes[Lara.meshPtrs[LM_RHAND]];
tmp = Lara.meshPtrs[LM_RHAND];
Lara.meshPtrs[LM_RHAND] = Meshes[Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND];
Lara.meshPtrs[LM_RHAND] = Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND;
Meshes[Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND] = tmp;
cart->Flags |= CF_MESH;

View file

@ -104,7 +104,7 @@ void CrocodileControl(short itemNumber)
ObjectInfo* obj;
CREATURE_INFO* crocodile;
AI_INFO info;
OBJECT_BONES boneRot;
OBJECT_Bones boneRot;
short angle;
short boneAngle;

View file

@ -261,7 +261,7 @@ void MutantControl(short itemNumber)
ITEM_INFO* item;
CREATURE_INFO* mutant;
AI_INFO info;
OBJECT_BONES mutant_joint;
OBJECT_Bones mutant_joint;
short frameNumber;
short headY;
short angle;
@ -337,9 +337,9 @@ void MutantControl(short itemNumber)
}
if (item->currentAnimState != MUTANT_LOCUST1)
mutant_joint = OBJECT_BONES(headY, info.xAngle, true);
mutant_joint = OBJECT_Bones(headY, info.xAngle, true);
else
mutant_joint = OBJECT_BONES(0);
mutant_joint = OBJECT_Bones(0);
CreatureJoint(item, 0, mutant_joint.bone0);
CreatureJoint(item, 1, mutant_joint.bone1);

View file

@ -221,10 +221,10 @@ void MissileControl(short itemNumber)
void ExplodeFX(FX_INFO* fx, int noXZVel, int bits)
{
short** meshpp = &Meshes[fx->frameNumber];
MESH* meshpp = &Meshes[fx->frameNumber];
ShatterItem.yRot = fx->pos.yRot;
ShatterItem.meshp = *meshpp;
ShatterItem.meshp = meshpp;
ShatterItem.sphere.x = fx->pos.xPos;
ShatterItem.sphere.y = fx->pos.yPos;
ShatterItem.sphere.z = fx->pos.zPos;

View file

@ -67,8 +67,8 @@ void InitAnimating(ObjectInfo* obj, int objectNumber)
obj->saveFlags = true;
obj->saveAnim = true;
obj->saveMesh = true;
Bones[obj->boneIndex + (0 * 4)] |= ROT_Y;
Bones[obj->boneIndex + (1 * 4)] |= ROT_X;
//Bones[obj->boneIndex + (0 * 4)] |= ROT_Y;
//Bones[obj->boneIndex + (1 * 4)] |= ROT_X;
}
}

View file

@ -147,7 +147,7 @@ namespace T5M::Renderer {
}
void Renderer11::updateAnimation(RendererItem * item, RendererObject * obj, short** frmptr, short frac, short rate, int mask, bool useObjectWorldRotation) {
RendererBone* bones[32];
RendererBone* Bones[32];
int nextBone = 0;
Matrix rotation;
@ -155,11 +155,11 @@ namespace T5M::Renderer {
Matrix* transforms = (item == NULL ? obj->AnimationTransforms.data() : &item->AnimationTransforms[0]);
// Push
bones[nextBone++] = obj->Skeleton;
Bones[nextBone++] = obj->Skeleton;
while (nextBone != 0) {
// Pop the last bone in the stack
RendererBone* bone = bones[--nextBone];
RendererBone* bone = Bones[--nextBone];
bool calculateMatrix = (mask >> bone->Index) & 1;
@ -211,7 +211,7 @@ namespace T5M::Renderer {
for (int i = 0; i < bone->Children.size(); i++) {
// Push
bones[nextBone++] = bone->Children[i];
Bones[nextBone++] = bone->Children[i];
}
}
}
@ -382,241 +382,64 @@ namespace T5M::Renderer {
}
}
RendererMesh* Renderer11::getRendererMeshFromTrMesh(RendererObject * obj, short* meshPtr, short boneIndex, int isJoints, int isHairs) {
RendererMesh* Renderer11::getRendererMeshFromTrMesh(RendererObject * obj, MESH* meshPtr, short boneIndex, int isJoints, int isHairs) {
RendererMesh* mesh = new RendererMesh();
short* basePtr = meshPtr;
mesh->Sphere = meshPtr->sphere;
short cx = *meshPtr++;
short cy = *meshPtr++;
short cz = *meshPtr++;
short r1 = *meshPtr++;
short r2 = *meshPtr++;
if (meshPtr->vertices.size() == 0)
return mesh;
mesh->Sphere = BoundingSphere(Vector3(cx, cy, cz), r1);
MESH_VERTEX * vertices = meshPtr->vertices.data();
short numVertices = *meshPtr++;
VECTOR* vertices = (VECTOR*)malloc(sizeof(VECTOR) * numVertices);
for (int v = 0; v < numVertices; v++) {
short x = *meshPtr++;
short y = *meshPtr++;
short z = *meshPtr++;
vertices[v].vx = x;
vertices[v].vy = y;
vertices[v].vz = z;
mesh->Positions.push_back(Vector3(x, y, z));
}
short numNormals = *meshPtr++;
VECTOR* normals = NULL;
short* colors = NULL;
if (numNormals > 0) {
normals = (VECTOR*)malloc(sizeof(VECTOR) * numNormals);
for (int v = 0; v < numNormals; v++) {
short x = *meshPtr++;
short y = *meshPtr++;
short z = *meshPtr++;
normals[v].vx = x;
normals[v].vy = y;
normals[v].vz = z;
}
}
else {
short numLights = -numNormals;
colors = (short*)malloc(sizeof(short) * numLights);
for (int v = 0; v < numLights; v++) {
colors[v] = *meshPtr++;
}
}
short numRectangles = *meshPtr++;
for (int r = 0; r < numRectangles; r++) {
short v1 = *meshPtr++;
short v2 = *meshPtr++;
short v3 = *meshPtr++;
short v4 = *meshPtr++;
short textureId = *meshPtr++;
short effects = *meshPtr++;
short indices[4] = { v1, v2, v3, v4 };
short textureIndex = textureId & 0x7FFF;
bool doubleSided = (textureId & 0x8000) >> 15;
// Get the object texture
OBJECT_TEXTURE* texture = &ObjectTextures[textureIndex];
int tile = texture->tileAndFlag & 0x7FFF;
// Create vertices
RendererBucket* bucket;
int bucketIndex = RENDERER_BUCKET_SOLID;
if (texture->attribute == 2 || (effects & 1))
bucketIndex = RENDERER_BUCKET_TRANSPARENT;
else
bucketIndex = RENDERER_BUCKET_SOLID;
// ColAddHorizon special handling
if (obj != NULL && obj->Id == ID_HORIZON && g_GameFlow->GetLevel(CurrentLevel)->ColAddHorizon) {
if (texture->attribute == 2 || (effects & 1))
bucketIndex = RENDERER_BUCKET_TRANSPARENT;
else
bucketIndex = RENDERER_BUCKET_SOLID;
}
bucket = &mesh->Buckets[bucketIndex];
if (obj != NULL)
obj->HasDataInBucket[bucketIndex] = true;
int baseVertices = bucket->NumVertices;
for (int v = 0; v < 4; v++) {
RendererVertex vertex;
vertex.Position.x = vertices[indices[v]].vx;
vertex.Position.y = vertices[indices[v]].vy;
vertex.Position.z = vertices[indices[v]].vz;
if (numNormals > 0) {
vertex.Normal.x = normals[indices[v]].vx / 16300.0f;
vertex.Normal.y = normals[indices[v]].vy / 16300.0f;
vertex.Normal.z = normals[indices[v]].vz / 16300.0f;
}
vertex.UV.x = texture->vertices[v].x;
vertex.UV.y = texture->vertices[v].y;
vertex.Bone = boneIndex;
if (isHairs)
vertex.Bone = indices[v];
if (colors == NULL) {
vertex.Color = Vector4::One * 0.5f;
}
else {
short shade = colors[indices[v]];
shade = (255 - shade * 255 / 8191) & 0xFF;
vertex.Color = Vector4(shade / 255.0f, shade / 255.0f, shade / 255.0f, 1.0f);
}
bucket->NumVertices++;
bucket->Vertices.push_back(vertex);
}
bucket->Indices.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 2);
bucket->Indices.push_back(baseVertices + 3);
bucket->Indices.push_back(baseVertices + 1);
bucket->NumIndices += 6;
RendererPolygon newPolygon;
newPolygon.Shape = SHAPE_RECTANGLE;
newPolygon.TextureId = textureId;
newPolygon.Indices[0] = baseVertices;
newPolygon.Indices[1] = baseVertices + 1;
newPolygon.Indices[2] = baseVertices + 2;
newPolygon.Indices[3] = baseVertices + 3;
bucket->Polygons.push_back(newPolygon);
}
short numTriangles = *meshPtr++;
for (int r = 0; r < numTriangles; r++) {
short v1 = *meshPtr++;
short v2 = *meshPtr++;
short v3 = *meshPtr++;
short textureId = *meshPtr++;
short effects = *meshPtr++;
short indices[3] = { v1, v2, v3 };
short textureIndex = textureId & 0x7FFF;
bool doubleSided = (textureId & 0x8000) >> 15;
// Get the object texture
OBJECT_TEXTURE* texture = &ObjectTextures[textureIndex];
int tile = texture->tileAndFlag & 0x7FFF;
// Create vertices
RendererBucket* bucket;
int bucketIndex = RENDERER_BUCKET_SOLID;
if (texture->attribute == 2 || (effects & 1))
bucketIndex = RENDERER_BUCKET_TRANSPARENT;
else
bucketIndex = RENDERER_BUCKET_SOLID;
bucket = &mesh->Buckets[bucketIndex];
if (obj != NULL)
obj->HasDataInBucket[bucketIndex] = true;
int baseVertices = bucket->NumVertices;
for (int v = 0; v < 3; v++) {
RendererVertex vertex;
vertex.Position.x = vertices[indices[v]].vx;
vertex.Position.y = vertices[indices[v]].vy;
vertex.Position.z = vertices[indices[v]].vz;
if (numNormals > 0) {
vertex.Normal.x = normals[indices[v]].vx / 16300.0f;
vertex.Normal.y = normals[indices[v]].vy / 16300.0f;
vertex.Normal.z = normals[indices[v]].vz / 16300.0f;
}
vertex.UV.x = texture->vertices[v].x;
vertex.UV.y = texture->vertices[v].y;
vertex.Bone = boneIndex;
if (isHairs)
vertex.Bone = indices[v];
if (colors == NULL) {
vertex.Color = Vector4::One * 0.5f;
}
else {
short shade = colors[indices[v]];
shade = (255 - shade * 255 / 8191) & 0xFF;
vertex.Color = Vector4(shade / 255.0f, shade / 255.0f, shade / 255.0f, 1.0f);
}
bucket->NumVertices++;
bucket->Vertices.push_back(vertex);
}
bucket->Indices.push_back(baseVertices);
bucket->Indices.push_back(baseVertices + 1);
bucket->Indices.push_back(baseVertices + 2);
bucket->NumIndices += 3;
RendererPolygon newPolygon;
newPolygon.Shape = SHAPE_TRIANGLE;
newPolygon.TextureId = textureId;
newPolygon.Indices[0] = baseVertices;
newPolygon.Indices[1] = baseVertices + 1;
newPolygon.Indices[2] = baseVertices + 2;
bucket->Polygons.push_back(newPolygon);
}
free(vertices);
if (normals != NULL)
free(normals);
if (colors != NULL)
free(colors);
unsigned int castedMeshPtr = reinterpret_cast<unsigned int>(basePtr);
if (m_meshPointersToMesh.find(castedMeshPtr) == m_meshPointersToMesh.end()) {
m_meshPointersToMesh.insert(pair<unsigned int, RendererMesh*>(castedMeshPtr, mesh));
}
/*else if (m_meshPointersToMesh[castedMeshPtr] == NULL)
for (int n = 0; n < meshPtr->buckets.size(); n++)
{
m_meshPointersToMesh[castedMeshPtr] = mesh;
}*/
BUCKET* levelBucket = &meshPtr->buckets[n];
RendererBucket* bucket;
int bucketIndex;
if (levelBucket->blendMode != 0)
bucketIndex = RENDERER_BUCKET_TRANSPARENT;
else
bucketIndex = RENDERER_BUCKET_SOLID;
bucket = &mesh->Buckets[bucketIndex];
for (int v = 0; v < levelBucket->indices.size(); v++)
{
int index = levelBucket->indices[v];
MESH_VERTEX* levelVertex = &vertices[index];
RendererVertex vertex;
vertex.Position.x = levelVertex->position.x;
vertex.Position.y = levelVertex->position.y;
vertex.Position.z = levelVertex->position.z;
vertex.Normal.x = levelVertex->normal.x;
vertex.Normal.y = levelVertex->normal.y;
vertex.Normal.z = levelVertex->normal.z;
vertex.UV.x = levelVertex->textureCoordinates.x;
vertex.UV.y = levelVertex->textureCoordinates.y;
vertex.Color.x = levelVertex->color.x;
vertex.Color.y = levelVertex->color.y;
vertex.Color.z = levelVertex->color.z;
vertex.Color.w = 1.0f;
vertex.Bone = boneIndex;
//vertex.Index = index;
if (isHairs)
vertex.Bone = index;
mesh->Positions.push_back(vertex.Position);
bucket->Indices.push_back(bucket->NumVertices);
bucket->NumVertices++;
bucket->Vertices.push_back(vertex);
}
}
m_meshes.push_back(mesh);
@ -924,8 +747,8 @@ namespace T5M::Renderer {
m_rooms[roomNumber2].Room = &Rooms[roomNumber2];
}
RendererMesh* Renderer11::getMeshFromMeshPtr(unsigned int meshp) {
return m_meshPointersToMesh[meshp];
RendererMesh* Renderer11::getMesh(int meshIndex) {
return m_meshes[meshIndex];
}
void Renderer11::GetLaraAbsBonePosition(Vector3 * pos, int joint) {

View file

@ -18,6 +18,8 @@
#include "ConstantBuffers/CameraMatrixBuffer.h"
#include "Texture2D/Texture2D.h"
#include <level.h>
namespace T5M::Renderer
{
#define MESH_BITS(x) (1 << x)
@ -27,7 +29,7 @@ namespace T5M::Renderer
constexpr auto MAX_LIGHTS_DRAW = 16384;
constexpr auto MAX_DYNAMIC_LIGHTS = 16384;
constexpr auto MAX_DRAW_STATICS = 16384;
constexpr auto MAX_BONES = 32;
constexpr auto MAX_Bones = 32;
constexpr auto MAX_SPRITES = 16384;
constexpr auto REFERENCE_RES_WIDTH = 800;
constexpr auto REFERENCE_RES_HEIGHT = 450;
@ -55,6 +57,7 @@ namespace T5M::Renderer
DirectX::SimpleMath::Vector2 UV;
DirectX::SimpleMath::Vector4 Color;
float Bone;
//int Index;
};
@ -475,7 +478,7 @@ namespace T5M::Renderer
int m_numSprites;
int m_numSpritesSequences;
std::vector<RendererSpriteSequence> m_spriteSequences;
std::unordered_map<unsigned int, RendererMesh*> m_meshPointersToMesh;
std::unordered_map<int, RendererMesh*> m_meshPointersToMesh;
DirectX::SimpleMath::Matrix m_LaraWorldMatrix;
std::vector<RendererAnimatedTextureSet> m_animatedTextureSets;
int m_numAnimatedTextureSets;
@ -525,7 +528,7 @@ namespace T5M::Renderer
ID3D11Buffer* createConstantBuffer(size_t size);
int getAnimatedTextureInfo(short textureId);
void initialiseHairRemaps();
RendererMesh* getRendererMeshFromTrMesh(RendererObject* obj, short* meshPtr, short boneIndex, int isJoints, int isHairs);
RendererMesh* getRendererMeshFromTrMesh(RendererObject* obj, MESH* meshPtr, short boneIndex, int isJoints, int isHairs);
void fromTrAngle(DirectX::SimpleMath::Matrix* matrix, short* frameptr, int index);
void buildHierarchy(RendererObject* obj);
void buildHierarchyRecursive(RendererObject* obj, RendererBone* node, RendererBone* parentNode);
@ -655,7 +658,7 @@ namespace T5M::Renderer
int GetSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, DirectX::SimpleMath::Matrix local);
void GetBoneMatrix(short itemNumber, int joint, DirectX::SimpleMath::Matrix* outMatrix);
RendererMesh* getMeshFromMeshPtr(unsigned int meshp);
RendererMesh* getMesh(int meshIndex);
private:
void drawFootprints();
void prepareCameraForFrame();

View file

@ -329,7 +329,7 @@ namespace T5M::Renderer {
// We need to override the bone index because the engine will take mesh 0 while drawing pistols anim,
// and vertices have bone index 0 and not 10
RendererMesh* mesh = getRendererMeshFromTrMesh(moveable,
Meshes[obj->meshIndex + j],
&Meshes[obj->meshIndex + j],
j, MoveablesIds[i] == ID_LARA_SKIN_JOINTS,
MoveablesIds[i] == ID_LARA_HAIR);
moveable->ObjectMeshes.push_back(mesh);
@ -341,16 +341,18 @@ namespace T5M::Renderer {
obj->nmeshes = 0;
}
else {
int* bone = &Bones[obj->boneIndex];
stack<RendererBone*> stack;
for (int j = 0; j < obj->nmeshes; j++) {
moveable->LinearizedBones.push_back(new RendererBone(j));
moveable->AnimationTransforms.push_back(Matrix::Identity);
moveable->BindPoseTransforms.push_back(Matrix::Identity);
}
if (obj->nmeshes > 1)
{
int* bone = &Bones[obj->boneIndex];
stack<RendererBone*> stack;
RendererBone* currentBone = moveable->LinearizedBones[0];
RendererBone* stackBone = moveable->LinearizedBones[0];
@ -410,6 +412,7 @@ namespace T5M::Renderer {
break;
}
}
}
for (int n = 0; n < obj->nmeshes; n++)
moveable->LinearizedBones[n]->Transform = Matrix::CreateTranslation(
@ -422,7 +425,7 @@ namespace T5M::Renderer {
// Fix Lara skin joints and hairs
if (MoveablesIds[i] == ID_LARA_SKIN_JOINTS) {
int bonesToCheck[2] = { 0,0 };
int BonesToCheck[2] = { 0,0 };
RendererObject* objSkin = m_moveableObjects[ID_LARA_SKIN];
@ -430,8 +433,8 @@ namespace T5M::Renderer {
RendererMesh* jointMesh = moveable->ObjectMeshes[j];
RendererBone* jointBone = moveable->LinearizedBones[j];
bonesToCheck[0] = jointBone->Parent->Index;
bonesToCheck[1] = j;
BonesToCheck[0] = jointBone->Parent->Index;
BonesToCheck[1] = j;
for (int b1 = 0; b1 < NUM_BUCKETS; b1++) {
RendererBucket* jointBucket = &jointMesh->Buckets[b1];
@ -442,8 +445,8 @@ namespace T5M::Renderer {
bool done = false;
for (int k = 0; k < 2; k++) {
RendererMesh* skinMesh = objSkin->ObjectMeshes[bonesToCheck[k]];
RendererBone* skinBone = objSkin->LinearizedBones[bonesToCheck[k]];
RendererMesh* skinMesh = objSkin->ObjectMeshes[BonesToCheck[k]];
RendererBone* skinBone = objSkin->LinearizedBones[BonesToCheck[k]];
for (int b2 = 0; b2 < NUM_BUCKETS; b2++) {
RendererBucket* skinBucket = &skinMesh->Buckets[b2];
@ -459,10 +462,15 @@ namespace T5M::Renderer {
int z2 = skinBucket->Vertices[v2].Position.z + skinBone->GlobalTranslation.z;
if (abs(x1 - x2) < 2 && abs(y1 - y2) < 2 && abs(z1 - z2) < 2) {
jointVertex->Bone = bonesToCheck[k];
jointVertex->Bone = BonesToCheck[k];
jointVertex->Position.x = skinVertex->Position.x;
jointVertex->Position.y = skinVertex->Position.y;
jointVertex->Position.z = skinVertex->Position.z;
Vector3 n = (jointVertex->Normal + skinVertex->Normal) / 2.0f;
n.Normalize();
jointVertex->Normal = n;
skinVertex->Normal = n;
done = true;
break;
}
@ -485,7 +493,7 @@ namespace T5M::Renderer {
RendererMesh* mesh = moveable->ObjectMeshes[j];
for (int n = 0; n < NUM_BUCKETS; n++) {
m_numHairVertices += mesh->Buckets[n].NumVertices;
m_numHairIndices += mesh->Buckets[n].NumIndices;
m_numHairIndices += mesh->Buckets[n].Indices.size();
}
}
@ -540,8 +548,7 @@ namespace T5M::Renderer {
RendererObject* staticObject = new RendererObject();
staticObject->Id = StaticObjectsIds[i];
short* meshPtr = Meshes[obj->meshNumber];
RendererMesh* mesh = getRendererMeshFromTrMesh(staticObject, Meshes[obj->meshNumber], 0, false, false);
RendererMesh* mesh = getRendererMeshFromTrMesh(staticObject, &Meshes[obj->meshNumber], 0, false, false);
staticObject->ObjectMeshes.push_back(mesh);

View file

@ -117,7 +117,7 @@ namespace T5M::Renderer {
updateConstantBuffer(m_cbMisc, &m_stMisc, sizeof(CMiscBuffer));
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc);
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
}
}
@ -258,7 +258,7 @@ namespace T5M::Renderer {
m_context->PSSetConstantBuffers(1, 1, &m_cbItem);
for (int k = 0; k < laraSkin->ObjectMeshes.size(); k++) {
RendererMesh* mesh = m_meshPointersToMesh[reinterpret_cast<unsigned int>(Lara.meshPtrs[k])];
RendererMesh* mesh = getMesh(Lara.meshPtrs[k]);
for (int j = 0; j < 2; j++) {
RendererBucket* bucket = &mesh->Buckets[j];
@ -267,7 +267,7 @@ namespace T5M::Renderer {
continue;
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -285,7 +285,7 @@ namespace T5M::Renderer {
continue;
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -301,7 +301,7 @@ namespace T5M::Renderer {
continue;
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -394,7 +394,7 @@ namespace T5M::Renderer {
if (bucket->NumVertices == 0)
continue;
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -580,7 +580,7 @@ namespace T5M::Renderer {
updateConstantBuffer(m_cbMisc, &m_stMisc, sizeof(CMiscBuffer));
m_context->PSSetConstantBuffers(3, 1, &m_cbMisc);
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
}
}
@ -1355,7 +1355,7 @@ namespace T5M::Renderer {
effect->BeginPass(iPass);
effect->CommitChanges();
drawPrimitives(D3DPT_TRIANGLELIST, 0, 0, bucket->NumVertices, 0, bucket->NumIndices / 3);
drawPrimitives(D3DPT_TRIANGLELIST, 0, 0, bucket->NumVertices, 0, bucket->Indices.size() / 3);
effect->EndPass();
}
@ -1386,8 +1386,7 @@ namespace T5M::Renderer {
RAT_STRUCT* rat = &Rats[i];
if (rat->on) {
short* meshPtr = Meshes[Objects[ID_RATS_EMITTER].meshIndex + (rand() % 8)];
RendererMesh* mesh = m_meshPointersToMesh[reinterpret_cast<unsigned int>(meshPtr)];
RendererMesh* mesh = getMesh(Objects[ID_RATS_EMITTER].meshIndex + (rand() % 8));
Matrix translation = Matrix::CreateTranslation(rat->pos.xPos, rat->pos.yPos, rat->pos.zPos);
Matrix rotation = Matrix::CreateFromYawPitchRoll(rat->pos.yRot, rat->pos.xRot, rat->pos.zRot);
Matrix world = rotation * translation;
@ -1403,7 +1402,7 @@ namespace T5M::Renderer {
if (bucket->NumVertices == 0)
continue;
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -1425,8 +1424,7 @@ namespace T5M::Renderer {
if (Objects[ID_BATS_EMITTER].loaded) {
ObjectInfo* obj = &Objects[ID_BATS_EMITTER];
RendererObject* moveableObj = m_moveableObjects[ID_BATS_EMITTER];
short* meshPtr = Meshes[Objects[ID_BATS_EMITTER].meshIndex + (-GlobalCounter & 3)];
RendererMesh* mesh = m_meshPointersToMesh[reinterpret_cast<unsigned int>(meshPtr)];
RendererMesh* mesh = getMesh(Objects[ID_BATS_EMITTER].meshIndex + (-GlobalCounter & 3));
for (int m = 0; m < 32; m++)
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
@ -1450,7 +1448,7 @@ namespace T5M::Renderer {
m_stItem.AmbientLight = m_rooms[bat->roomNumber].AmbientLight;
updateConstantBuffer(m_cbItem, &m_stItem, sizeof(CItemBuffer));
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -2074,7 +2072,7 @@ namespace T5M::Renderer {
continue;
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -2141,7 +2139,7 @@ namespace T5M::Renderer {
continue;
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -2398,7 +2396,7 @@ namespace T5M::Renderer {
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}

View file

@ -536,7 +536,7 @@ namespace T5M::Renderer {
updateConstantBuffer(m_cbItem, &m_stItem, sizeof(CItemBuffer));
m_context->VSSetConstantBuffers(1, 1, &m_cbItem);
m_context->DrawIndexed(flashBucket->NumIndices, flashBucket->StartIndex, 0);
m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0);
m_numDrawCalls++;
}
@ -549,7 +549,7 @@ namespace T5M::Renderer {
updateConstantBuffer(m_cbItem, &m_stItem, sizeof(CItemBuffer));
m_context->VSSetConstantBuffers(1, 1, &m_cbItem);
m_context->DrawIndexed(flashBucket->NumIndices, flashBucket->StartIndex, 0);
m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -624,7 +624,7 @@ namespace T5M::Renderer {
updateConstantBuffer(m_cbItem, &m_stItem, sizeof(CItemBuffer));
m_context->VSSetConstantBuffers(1, 1, &m_cbItem);
m_context->DrawIndexed(flashBucket->NumIndices, flashBucket->StartIndex, 0);
m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -967,7 +967,7 @@ namespace T5M::Renderer {
continue;
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}

View file

@ -404,14 +404,11 @@ namespace T5M::Renderer {
newEffect->Effect = fx;
newEffect->Id = fxNum;
newEffect->World = Matrix::CreateFromYawPitchRoll(fx->pos.yRot, fx->pos.xPos, fx->pos.zPos) * Matrix::CreateTranslation(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos);
newEffect->Mesh = m_meshPointersToMesh[reinterpret_cast<unsigned int>(Meshes[(obj->nmeshes ? obj->meshIndex : fx->frameNumber)])];
newEffect->Mesh = getMesh(obj->nmeshes ? obj->meshIndex : fx->frameNumber);
collectLightsForEffect(fx->roomNumber, newEffect);
m_effectsToDraw.push_back(newEffect);
short* mp = Meshes[(obj->nmeshes ? obj->meshIndex : fx->frameNumber)];
short hhh = 0;
}
}

View file

@ -80,7 +80,8 @@ bool Renderer11::Initialise(int w, int h, int refreshRate, bool windowed, HWND h
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"BLENDINDICES", 0, DXGI_FORMAT_R32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"BLENDINDICES", 0, DXGI_FORMAT_R32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0}/*,
{"TEXCOORD", 1, DXGI_FORMAT_R32_UINT, 0, 52, D3D11_INPUT_PER_VERTEX_DATA, 0},*/
};
m_inputLayout = NULL;

View file

@ -136,6 +136,8 @@ void Renderer11::UpdateLaraAnimations(bool force)
laraObj->AnimationTransforms[m] = item->AnimationTransforms[m];
// At this point, Lara's matrices are ready. Now let's do ponytails...
// TODO: disabled for now
/*
if (m_moveableObjects[ID_LARA_HAIR] != NULL)
{
RendererObject* hairsObj = m_moveableObjects[ID_LARA_HAIR];
@ -262,7 +264,7 @@ void Renderer11::UpdateLaraAnimations(bool force)
}
}
}
}
}*/
m_items[Lara.itemNumber].DoneAnimations = true;
}
@ -334,7 +336,7 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
for (int k = 0; k < laraSkin->ObjectMeshes.size(); k++)
{
RendererMesh* mesh = m_meshPointersToMesh[reinterpret_cast<unsigned int>(Lara.meshPtrs[k])];
RendererMesh* mesh = getMesh(Lara.meshPtrs[k]);
for (int j = firstBucket; j < lastBucket; j++)
{
@ -344,7 +346,7 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
continue;
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -365,7 +367,7 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
continue;
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
@ -373,7 +375,7 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
if (!transparent)
{
for (int k = 0; k < laraSkin->ObjectMeshes.size(); k++)
/*for (int k = 0; k < laraSkin->ObjectMeshes.size(); k++)
{
RendererMesh* mesh = laraSkin->ObjectMeshes[k];
@ -385,13 +387,13 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
continue;
// Draw vertices
m_context->DrawIndexed(bucket->NumIndices, bucket->StartIndex, 0);
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
m_numDrawCalls++;
}
}
}*/
// Hairs are pre-transformed
Matrix matrices[8] = { Matrix::Identity, Matrix::Identity, Matrix::Identity, Matrix::Identity,
/*Matrix matrices[8] = { Matrix::Identity, Matrix::Identity, Matrix::Identity, Matrix::Identity,
Matrix::Identity, Matrix::Identity, Matrix::Identity, Matrix::Identity };
memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix) * 8);
m_stItem.World = Matrix::Identity;
@ -402,7 +404,7 @@ bool Renderer11::drawLara(bool transparent, bool shadowMap)
m_primitiveBatch->Begin();
m_primitiveBatch->DrawIndexed(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, (const uint16_t*)m_hairIndices.data(), m_numHairIndices, m_hairVertices.data(), m_numHairVertices);
m_primitiveBatch->End();
}
}*/
}
return true;

View file

@ -12,11 +12,12 @@
#include "door.h"
#include "box.h"
#include "sound.h"
#include "levelloader.h"
#include "GameFlowScript.h"
using T5M::Renderer::g_Renderer;
using std::vector;
using std::string;
ChunkId* ChunkTriggersList = ChunkId::FromString("Tr5Triggers");
ChunkId* ChunkTrigger = ChunkId::FromString("Tr5Trigger");
ChunkId* ChunkLuaIds = ChunkId::FromString("Tr5LuaIds");
@ -24,17 +25,13 @@ ChunkId* ChunkLuaId = ChunkId::FromString("Tr5LuaId");
extern GameScript* g_GameScript;
short* RawMeshData;
int MeshDataSize;
int* MeshTrees;
int* RawMeshPointers;
std::vector<int> Bones;
std::vector<MESH> Meshes;
int NumObjects;
int NumStaticObjects;
int NumMeshPointers;
int NumObjectTextures;
int NumTextureTiles;
short* MeshBase;
short** Meshes;
int NumItems;
FILE* LevelFilePtr;
@ -57,7 +54,6 @@ ANIM_STRUCT* Anims;
CHANGE_STRUCT* Changes;
RANGE_STRUCT* Ranges;
short* Commands;
int* Bones;
short* Frames;
int AnimationsCount;
short* FloorData;
@ -76,8 +72,6 @@ int g_NumSpritesSequences;
ChunkReader* g_levelChunkIO;
TrLevel g_Level;
short ReadInt8()
{
byte value = *(byte*)LevelDataPtr;
@ -187,25 +181,56 @@ void LoadObjects()
memset(Objects, 0, sizeof(ObjectInfo) * ID_NUMBER_OBJECTS);
memset(StaticObjects, 0, sizeof(StaticInfo) * MAX_STATICS);
int numMeshDataWords = ReadInt32();
int numMeshDataBytes = 2 * numMeshDataWords;
MeshBase = (short*)game_malloc(numMeshDataBytes);
ReadBytes(MeshBase, numMeshDataBytes);
MeshDataSize = numMeshDataBytes;
int numMeshPointers = ReadInt32();
Meshes = (short**)game_malloc(sizeof(short*) * numMeshPointers);
ReadBytes(Meshes, sizeof(short*) * numMeshPointers);
for (int i = 0; i < numMeshPointers; i++)
int numMeshes = ReadInt32();
Meshes.reserve(numMeshes);
for (int i = 0; i < numMeshes; i++)
{
Meshes[i] = &MeshBase[(int)Meshes[i] / 2];
MESH mesh;
mesh.sphere = BoundingSphere(Vector3(ReadFloat(), ReadFloat(), ReadFloat()), ReadFloat());
int numVertices = ReadInt32();
mesh.vertices.reserve(numVertices);
for (int j = 0; j < numVertices; j++)
{
MESH_VERTEX vertex;
vertex.position.x = ReadFloat();
vertex.position.y = ReadFloat();
vertex.position.z = ReadFloat();
vertex.normal.x = ReadFloat();
vertex.normal.y = ReadFloat();
vertex.normal.z = ReadFloat();
vertex.textureCoordinates.x = ReadFloat();
vertex.textureCoordinates.y = ReadFloat();
vertex.color.x = ReadFloat();
vertex.color.y = ReadFloat();
vertex.color.z = ReadFloat();
ReadFloat();
vertex.bone = ReadInt32();
vertex.index = ReadInt32();
mesh.vertices.push_back(vertex);
}
int numMeshes = numMeshPointers;
NumMeshPointers = numMeshes;
int numBuckets = ReadInt32();
mesh.buckets.reserve(numBuckets);
for (int j = 0; j < numBuckets; j++)
{
BUCKET bucket;
bucket.texture = ReadInt32();
bucket.blendMode = ReadInt8();
bucket.animated = ReadInt8();
int numIndices = ReadInt32();
bucket.indices.reserve(numIndices);
for (int k = 0; k < numIndices; k++)
bucket.indices.push_back(ReadInt32());
mesh.buckets.push_back(bucket);
}
Meshes.push_back(mesh);
}
int numAnimations = ReadInt32();
Anims = (ANIM_STRUCT*)game_malloc(sizeof(ANIM_STRUCT) * numAnimations);
@ -224,22 +249,12 @@ void LoadObjects()
ReadBytes(Commands, sizeof(short) * numCommands);
int numBones = ReadInt32();
Bones = (int*)game_malloc(sizeof(int) * numBones);
ReadBytes(Bones, sizeof(int) * numBones);
int* bone = Bones;
for (int i = 0; i < 15; i++)
Bones.reserve(numBones);
for (int i = 0; i < numBones; i++)
{
int opcode = *(bone++);
int linkX = *(bone++);
int linkY = *(bone++);
int linkZ = *(bone++);
Bones.push_back(ReadInt32());
}
MeshTrees = (int*)game_malloc(sizeof(int) * numBones);
memcpy(MeshTrees, Bones, sizeof(int) * numBones);
int numFrames = ReadInt32();
Frames = (short*)game_malloc(sizeof(short) * numFrames);
ReadBytes(Frames, sizeof(short) * numFrames);
@ -260,11 +275,11 @@ void LoadObjects()
MoveablesIds.push_back(objNum);
Objects[objNum].loaded = true;
Objects[objNum].nmeshes = ReadInt16();
Objects[objNum].meshIndex = ReadInt16();
Objects[objNum].nmeshes = (short)ReadInt16();
Objects[objNum].meshIndex = (short)ReadInt16();
Objects[objNum].boneIndex = ReadInt32();
Objects[objNum].frameBase = (short*)(ReadInt32() + (int)Frames);
Objects[objNum].animIndex = ReadInt16();
Objects[objNum].animIndex = (short)ReadInt16();
ReadInt16();
@ -281,7 +296,7 @@ void LoadObjects()
int meshID = ReadInt32();
StaticObjectsIds.push_back(meshID);
StaticObjects[meshID].meshNumber = ReadInt16();
StaticObjects[meshID].meshNumber = (short)ReadInt16();
StaticObjects[meshID].yMinp = ReadInt16();
StaticObjects[meshID].xMaxp = ReadInt16();
@ -297,7 +312,7 @@ void LoadObjects()
StaticObjects[meshID].zMinc = ReadInt16();
StaticObjects[meshID].zMaxc = ReadInt16();
StaticObjects[meshID].flags = ReadInt16();
StaticObjects[meshID].flags = (short)ReadInt16();
}
// HACK: to remove after decompiling LoadSprites
@ -442,6 +457,7 @@ void ReadRooms()
vertex.color.y = ReadFloat();
vertex.color.z = ReadFloat();
vertex.effects = ReadInt32();
vertex.index = ReadInt32();
room.vertices.push_back(vertex);
}
@ -736,6 +752,9 @@ void FreeLevel()
StaticsTextures.clear();
SpritesTextures.clear();
ObjectTextures.clear();
Bones.clear();
Meshes.clear();
MoveablesIds.clear();
g_Renderer.FreeRendererData();
g_GameScript->FreeLevelScripts();
}

View file

@ -8,7 +8,7 @@
#include "room.h"
#define AddPtr(p, t, n) p = (t*)((char*)(p) + (ptrdiff_t)(n));
#define MESHES(slot, mesh) Meshes[Objects[slot].meshIndex + mesh]
#define MESHES(slot, mesh) (Objects[slot].meshIndex + mesh)
struct ChunkId;
struct LEB128;
@ -28,30 +28,15 @@ typedef struct OBJECT_TEXTURE
int destination;
};
#pragma pack(push, 1)
struct tr_object_texture_vert
struct TEXTURE
{
byte Xcoordinate; // 1 if Xpixel is the low value, 255 if Xpixel is the high value in the object texture
byte Xpixel;
byte Ycoordinate; // 1 if Ypixel is the low value, 255 if Ypixel is the high value in the object texture
byte Ypixel;
int width;
int height;
int size;
std::vector<byte> data;
};
struct tr4_object_texture
{
short Attribute;
short TileAndFlag;
short NewFlags;
tr_object_texture_vert Vertices[4]; // The four corners of the texture
int OriginalU;
int OriginalV;
int Width; // Actually width-1
int Height; // Actually height-1
short Padding;
};
#pragma pack(pop)
typedef struct AIOBJECT
struct AIOBJECT
{
short objectNumber;
short roomNumber;
@ -64,14 +49,14 @@ typedef struct AIOBJECT
short boxNumber;
};
typedef struct CHANGE_STRUCT
struct CHANGE_STRUCT
{
short goalAnimState;
short numberRanges;
short rangeIndex;
};
typedef struct RANGE_STRUCT
struct RANGE_STRUCT
{
short startFrame;
short endFrame;
@ -79,7 +64,7 @@ typedef struct RANGE_STRUCT
short linkFrameNum;
};
typedef struct SPRITE
struct SPRITE
{
int tile;
float x1;
@ -92,26 +77,37 @@ typedef struct SPRITE
float y4;
};
extern short* MeshData;
extern int MeshDataSize;
struct MESH_VERTEX
{
Vector3 position;
Vector3 normal;
Vector2 textureCoordinates;
Vector3 color;
int bone;
int index;
};
struct MESH
{
BoundingSphere sphere;
std::vector<MESH_VERTEX> vertices;
std::vector<BUCKET> buckets;
};
extern OBJECT_TEXTURE* NewObjectTextures;
extern uintptr_t hLoadLevel;
extern int NumMeshPointers;
extern int* MeshTrees;
extern std::vector<int> Bones;
extern int NumObjects;
extern int NumStaticObjects;
extern std::vector<int> MoveablesIds;
extern std::vector<int> StaticObjectsIds;
extern int* RawMeshPointers;
extern short* RawMeshData;
extern int NumObjectTextures;
extern char* LevelDataPtr;
extern int IsLevelLoading;
extern int NumTextureTiles;
extern int g_NumSprites;
extern int g_NumSpritesSequences;
extern short* MeshBase;
extern short** Meshes;
extern std::vector<MESH> Meshes;
extern int NumItems;
extern std::vector<OBJECT_TEXTURE> ObjectTextures;
extern ITEM_INFO* Items;
@ -121,7 +117,6 @@ extern ANIM_STRUCT* Anims;
extern CHANGE_STRUCT* Changes;
extern RANGE_STRUCT* Ranges;
extern short* Commands;
extern int* Bones;
extern short* Frames;
extern int AnimationsCount;
extern short* FloorData;
@ -135,8 +130,6 @@ extern std::vector<TEXTURE> StaticsTextures;
extern std::vector<TEXTURE> SpritesTextures;
extern TEXTURE MiscTextures;
extern TrLevel g_Level;
void LoadTextures();
void LoadRooms();
int LoadItems();

File diff suppressed because it is too large Load diff

View file

@ -1,101 +0,0 @@
#pragma once
#include "framework.h"
#include "sound.h"
#include "Streams.h"
#include "newtypes.h"
#include "ChunkId.h"
#include "ChunkReader.h"
class LevelLoader
{
private:
ChunkId* m_chunkTextureAtlas = ChunkId::FromString("T5MTex");
ChunkId* m_chunkTextureColor = ChunkId::FromString("T5MTexColMap");
ChunkId* m_chunkTextureNormalMap = ChunkId::FromString("T5MTexNrmMap");
ChunkId* m_chunkRoom = ChunkId::FromString("T5MRoom");
ChunkId* m_chunkRoomInfo = ChunkId::FromString("T5MRoomInfo");
ChunkId* m_chunkBucket = ChunkId::FromString("T5MBckt");
ChunkId* m_chunkRoomLight = ChunkId::FromString("T5MLight");
ChunkId* m_chunkRoomStatic = ChunkId::FromString("T5MRoomSt");
ChunkId* m_chunkRoomPortal = ChunkId::FromString("T5MPortal");
ChunkId* m_chunkRoomSector = ChunkId::FromString("T5MSector");
ChunkId* m_chunkRoomTriggerVolume = ChunkId::FromString("T5MTrigVol");
ChunkId* m_chunkRoomClimbVolume = ChunkId::FromString("T5MClimbVol");
ChunkId* m_chunkMaterial = ChunkId::FromString("T5MMat");
ChunkId* m_chunkVerticesPositions = ChunkId::FromString("T5MVrtPos");
ChunkId* m_chunkVerticesNormals = ChunkId::FromString("T5MVrtN");
ChunkId* m_chunkVerticesTextureCoords = ChunkId::FromString("T5MVrtUV");
ChunkId* m_chunkVerticesColors = ChunkId::FromString("T5MVrtCol");
ChunkId* m_chunkVerticesEffects = ChunkId::FromString("T5MVrtFX");
ChunkId* m_chunkVerticesBones = ChunkId::FromString("T5MVrtB");
ChunkId* m_chunkPolygon = ChunkId::FromString("T5MPoly");
ChunkId* m_chunkMesh = ChunkId::FromString("T5MMesh");
ChunkId* m_chunkBone = ChunkId::FromString("T5MBone");
ChunkId* m_chunkKeyFrame = ChunkId::FromString("T5MKf");
ChunkId* m_chunkAnimCommand = ChunkId::FromString("T5MAnCmd");
ChunkId* m_chunkStateChange = ChunkId::FromString("T5MStCh");
ChunkId* m_chunkAnimDispatch = ChunkId::FromString("T5MAnDisp");
ChunkId* m_chunkAnimation = ChunkId::FromString("T5MAnim");
ChunkId* m_chunkMoveable = ChunkId::FromString("T5MMoveable");
ChunkId* m_chunkStatic = ChunkId::FromString("T5MStatic");
ChunkId* m_chunkItem = ChunkId::FromString("T5MItem");
ChunkId* m_chunkAiItem = ChunkId::FromString("T5MAiItem");
ChunkId* m_chunkCamera = ChunkId::FromString("T5MCamera");
ChunkId* m_chunkSink = ChunkId::FromString("T5MSink");
ChunkId* m_chunkFlybyCamera = ChunkId::FromString("T5MFlyBy");
ChunkId* m_chunkSoundSource = ChunkId::FromString("T5MSndSrc");
ChunkId* m_chunkBox = ChunkId::FromString("T5MBox");
ChunkId* m_chunkOverlap = ChunkId::FromString("T5MOv");
ChunkId* m_chunkZone = ChunkId::FromString("T5MZone");
ChunkId* m_chunkSoundMap = ChunkId::FromString("T5MSoundMap");
ChunkId* m_chunkSoundDetail = ChunkId::FromString("T5MSndDet");
ChunkId* m_chunkSample = ChunkId::FromString("T5MSam");
ChunkId* m_chunkLeelScript = ChunkId::FromString("T5MScript");
ChunkId* m_chunkSprite = ChunkId::FromString("T5MSpr");
ChunkId* m_chunkSpriteSequence = ChunkId::FromString("T5MSprSeq");
ChunkId* m_chunkDummy = ChunkId::FromString("T5MDummy");
ChunkId* m_chunkAnimatedTextureSequence = ChunkId::FromString("T5MAnTxSeq");
ChunkId* m_chunkAnimatedTextureFrame = ChunkId::FromString("T5MAnTxFr");
ChunkId* m_chunkFloorData = ChunkId::FromString("T5MFloorData");
int m_magicNumber = 0x4D355254;
std::string m_filename;
ChunkReader* m_reader;
FileStream* m_stream;
int m_numSamples = 0;
TrLevel m_level;
bool readTexture();
bool readAnimatedTextureSequence();
bool readRoom();
bool readBucket(TrBucket* bucket);
bool readMesh();
bool readAnimation();
bool readChange();
bool readDispatch();
bool readBone();
bool readKeyFrame();
bool readCommand();
bool readOverlap();
bool readFloorData();
bool readMoveable();
bool readStatic();
bool readSpriteSequence();
bool readItem();
bool readAiItem();
bool readSink();
bool readCamera();
bool readFlybyCamera();
bool readSoundSource();
bool readBox();
bool readZones();
bool readSoundMap();
bool readSoundDetail();
bool readSample();
public:
LevelLoader(std::string filename);
~LevelLoader();
bool Load();
bool FillLegacyData();
};

View file

@ -1,386 +1,10 @@
#pragma once
#include "framework.h"
struct TEXTURE
{
int width;
int height;
int size;
std::vector<byte> data;
};
struct TrTexturePage
{
int width;
int height;
int flags;
int format;
byte* colorMap;
byte* normalMap;
};
struct TrPolygon
{
std::vector<int> indices;
int animatedSequence;
int frame;
};
struct TrMaterial
struct BUCKET
{
int texture;
byte blendMode;
bool animated;
};
struct TrBucket
{
TrMaterial material;
std::vector<Vector3> positions;
std::vector<Vector3> colors;
std::vector<Vector2> textureCoords;
std::vector<Vector3> normals;
std::vector<int> verticesEffects;
std::vector<int> bones;
std::vector<TrPolygon> polygons;
};
struct TrVolume
{
int type;
Vector3 position;
Quaternion rotation;
BoundingBox box;
BoundingSphere sphere;
std::string script;
};
struct TrClimbVolume : TrVolume
{
int climbType;
};
struct TrTriggerVolume : TrVolume
{
int activators;
};
struct TrSector
{
int floorDataIndex;
int floorDataCount;
int box;
int pathfindingFlags;
int stepSound;
int roomBelow;
int roomAbove;
int floor;
int ceiling;
std::vector<int> floorData;
};
struct TrLight
{
Vector3 position;
Vector3 color;
Vector3 direction;
byte type;
bool castShadows;
float intensity;
float in;
float out;
float len;
float cutoff;
int flags;
};
struct TrRoomStatic
{
std::string name;
Vector3 position;
Quaternion rotation;
Vector3 scale;
int staticNumber;
Vector3 color;
bool receiveShadows;
bool castShadows;
int flags;
std::string script;
};
struct TrPortal
{
int adjoiningRoom;
Vector3 normal;
std::vector<Vector3> vertices;
};
struct TrRoom
{
int x;
int z;
int yBottom;
int yTop;
int numXsectors;
int numZsectors;
int roomType;
int reverb;
int effect;
float effectStrength;
int alternateRoom;
int alternatGroup;
int flags;
Vector3 ambient;
std::vector<TrBucket> buckets;
std::vector<TrLight> lights;
std::vector<TrRoomStatic> statics;
std::vector<TrSector> sectors;
std::vector<TrPortal> portals;
std::vector<TrTriggerVolume> triggers;
std::vector<TrClimbVolume> climbVolumes;
int itemNumber;
int fxNumber;
};
struct TrMesh
{
BoundingSphere sphere;
std::vector<TrBucket> buckets;
};
struct TrBone
{
int opcode;
Vector3 offset;
};
struct TrKeyFrame
{
Vector3 origin;
BoundingBox boundingBox;
std::vector<Quaternion> angles;
};
struct TrAnimCommand
{
int type;
int frame;
std::vector<int> params;
};
struct TrAnimDispatch
{
int inFrame;
int outFrame;
int nextAnimation;
int nextFrame;
};
struct TrStateChange
{
int state;
int dispatchIndex;
int dispatchCount;
std::vector<TrAnimDispatch> dispatches;
};
struct TrAnimation
{
int framerate;
int state;
int nextAnimation;
int nextFrame;
int frameBase;
int frameEnd;
float speed;
float acceleration;
float lateralSpeed;
float lateralAcceleration;
int framesIndex;
int framesCount;
int changesIndex;
int changesCount;
int commandsIndex;
int commandsCount;
std::vector<TrKeyFrame> keyframes;
std::vector<TrStateChange> changes;
std::vector<TrAnimCommand> commands;
};
struct TrMoveable
{
int id;
int animationIndex;
int animationCount;
int meshIndex;
int meshCount;
int bonesIndex;
int bonesCount;
std::vector<TrMesh> meshes;
std::vector<TrBone> bones;
std::vector<TrAnimation> animations;
};
struct TrStatic
{
int id;
BoundingBox visibilityBox;
BoundingBox collisionBox;
int meshNumber;
int meshCount;
std::vector<TrMesh> meshes;
};
struct TrAnimatedTexturesFrame
{
int texture;
std::vector<Vector2> textureCoords;
};
struct TrAnimatedTexturesSequence
{
byte animationType;
float fps;
int uvRotate;
std::vector<TrAnimatedTexturesFrame> frames;
};
struct TrItem
{
std::string name;
Vector3 position;
Quaternion rotation;
float angle;
Vector3 scale;
Vector3 color;
int roomNumber;
int objectNumber;
std::string script;
};
struct TrCamera
{
std::string name;
Vector3 position;
int roomNumber;
int type;
int flags;
std::string script;
};
struct TrSoundSource
{
std::string name;
Vector3 position;
int roomNumber;
float volume;
int sound;
int playMode;
};
struct TrSink
{
std::string name;
Vector3 position;
int roomNumber;
float strength;
int box;
};
struct TrOverlap
{
int flags;
int box;
};
struct TrBox
{
Vector2 min;
Vector2 max;
int floor;
int flags;
int overlapsIndex;
int overlapsCount;
std::vector<TrOverlap> overlaps;
};
struct TrSample
{
int uncompressedSize;
int compressedSize;
byte* data;
};
struct TrSoundDetails
{
float volume;
float range;
float chance;
float pitch;
bool randomizePitch;
bool randomizeGain;
bool noPanoramic;
byte loop;
std::vector<TrSample> samples;
};
struct TrFlybyCamera
{
std::string name;
int sequence;
int number;
Vector3 position;
Vector3 direction;
float fov;
float roll;
float speed;
int timer;
int roomNumber;
int flags;
std::string script;
};
struct TrSprite
{
int texture;
std::vector<Vector2> textureCoords;
};
struct TrSpriteSequence
{
int id;
int spritesIndex;
int spritesCount;
std::vector<TrSprite> sprites;
};
struct TrLevel
{
std::vector<TrTexturePage> textures;
std::vector<TrRoom> rooms;
std::vector<int> floorData;
std::vector<TrMesh> meshes;
std::vector<TrAnimation> animations;
std::vector<TrBone> bones;
std::vector<TrStateChange> changes;
std::vector<TrAnimDispatch> dispatches;
std::vector<TrKeyFrame> frames;
std::vector<TrAnimCommand> commands;
std::vector<TrAnimatedTexturesSequence> animatedTextures;
std::vector<TrSprite> sprites;
std::vector<TrSpriteSequence> spriteSequences;
std::vector<int> soundMap;
std::vector<TrSoundDetails> soundDetails;
std::vector<TrSample> samples;
std::vector<TrItem> items;
std::vector<TrItem> aiItems;
std::vector<TrMoveable> moveables;
std::vector<TrStatic> statics;
std::vector<TrBox> boxes;
std::vector<TrOverlap> overlaps;
std::vector<int> zones[5][2];
std::vector<TrSink> sinks;
std::vector<TrCamera> cameras;
std::vector<TrSoundSource> soundSources;
std::vector<TrFlybyCamera> flybyCameras;
std::vector<int> indices;
};

View file

@ -387,7 +387,6 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts"</Command>
<ClInclude Include="Specific\input.h" />
<ClInclude Include="Specific\IO\Streams.h" />
<ClInclude Include="Specific\level.h" />
<ClInclude Include="Specific\levelloader.h" />
<ClInclude Include="Specific\newtypes.h" />
<ClInclude Include="Specific\setup.h" />
<ClInclude Include="Specific\winmain.h" />
@ -627,7 +626,6 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts"</Command>
<ClCompile Include="Specific\IO\ChunkReader.cpp" />
<ClCompile Include="Specific\IO\Streams.cpp" />
<ClCompile Include="Specific\level.cpp" />
<ClCompile Include="Specific\levelloader.cpp" />
<ClCompile Include="Specific\setup.cpp" />
<ClCompile Include="Specific\winmain.cpp" />
<ClCompile Include="Objects\TR5\Object\tr5_genslot.cpp" />

View file

@ -699,9 +699,6 @@
<ClInclude Include="Game\lara_struct.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="Specific\levelloader.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="Specific\newtypes.h">
<Filter>File di intestazione</Filter>
</ClInclude>
@ -1424,9 +1421,6 @@
<ClCompile Include="Game\trmath.cpp">
<Filter>File di origine</Filter>
</ClCompile>
<ClCompile Include="Specific\levelloader.cpp">
<Filter>File di origine</Filter>
</ClCompile>
<ClCompile Include="Objects\TR5\Light\tr5_light.cpp">
<Filter>File di origine</Filter>
</ClCompile>