2020-12-21 13:16:29 -03:00
|
|
|
#include "framework.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Renderer/Renderer11.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Specific/configuration.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Game/camera.h"
|
|
|
|
#include "Game/animation.h"
|
|
|
|
#include "Specific/setup.h"
|
|
|
|
#include "Specific/level.h"
|
|
|
|
#include "Game/control/control.h"
|
|
|
|
#include "Game/Lara/lara.h"
|
|
|
|
#include "Game/collision/sphere.h"
|
2022-02-06 15:02:16 +00:00
|
|
|
#include "Scripting/Flow/ScriptInterfaceFlowHandler.h"
|
2021-01-21 19:35:57 +01:00
|
|
|
#include "Renderer\RenderView\RenderView.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Objects/TR3/Vehicles/quad.h"
|
2021-12-24 11:08:16 +03:00
|
|
|
#include "Objects/TR3/Vehicles/rubberboat.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Objects/TR3/Vehicles/upv.h"
|
|
|
|
#include "Objects/TR3/Vehicles/biggun.h"
|
|
|
|
#include "Objects/TR4/Vehicles/jeep.h"
|
|
|
|
#include "Objects/TR4/Vehicles/motorbike.h"
|
2020-12-21 13:16:29 -03:00
|
|
|
#include <algorithm>
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Game/itemdata/creature_info.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Objects/TR3/Vehicles/quad_info.h"
|
|
|
|
#include "Objects/TR4/Vehicles/jeep_info.h"
|
|
|
|
#include "Objects/TR4/Vehicles/motorbike_info.h"
|
|
|
|
#include "Objects/TR3/Vehicles/rubberboat_info.h"
|
|
|
|
#include "Objects/TR3/Vehicles/upv_info.h"
|
|
|
|
#include "Objects/TR3/Vehicles/biggun_info.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Game/items.h"
|
2021-09-25 11:27:47 +02:00
|
|
|
|
2020-12-21 13:16:29 -03:00
|
|
|
extern GameConfiguration g_Configuration;
|
2022-02-06 15:02:16 +00:00
|
|
|
extern ScriptInterfaceFlowHandler *g_GameFlow;
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2021-08-30 18:03:21 +03:00
|
|
|
namespace TEN::Renderer
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
|
|
|
using std::pair;
|
|
|
|
using std::vector;
|
|
|
|
|
2022-01-29 05:55:09 +01:00
|
|
|
bool Renderer11::IsRoomUnderwater(short roomNumber)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2021-12-09 06:33:19 +01:00
|
|
|
return (g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER);
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
bool Renderer11::IsInRoom(int x, int y, int z, short roomNumber)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2021-12-09 06:33:19 +01:00
|
|
|
ROOM_INFO* r = &g_Level.Rooms[roomNumber];
|
2020-12-21 13:16:29 -03:00
|
|
|
|
|
|
|
return (x >= r->x && x <= r->x + r->xSize * 1024.0f &&
|
|
|
|
y >= r->maxceiling && y <= r->minfloor &&
|
2021-11-08 17:28:04 +03:00
|
|
|
z >= r->z && z <= r->z + r->zSize * 1024.0f);
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
std::vector<TEN::Renderer::RendererVideoAdapter>* Renderer11::GetAdapters()
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
|
|
|
return &m_adapters;
|
|
|
|
}
|
|
|
|
|
2022-01-29 05:55:09 +01:00
|
|
|
void Renderer11::UpdateEffects(RenderView& view)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2021-12-09 11:34:58 +01:00
|
|
|
for (auto room : view.roomsToDraw)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2021-12-09 11:34:58 +01:00
|
|
|
for (auto fx : room->EffectsToDraw)
|
|
|
|
{
|
2022-03-31 23:55:54 +11:00
|
|
|
Matrix translation = Matrix::CreateTranslation(fx->Effect->pos.Position.x, fx->Effect->pos.Position.y, fx->Effect->pos.Position.z);
|
|
|
|
Matrix rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(fx->Effect->pos.Orientation.y), TO_RAD(fx->Effect->pos.Orientation.x), TO_RAD(fx->Effect->pos.Orientation.z));
|
2021-12-09 11:34:58 +01:00
|
|
|
fx->World = rotation * translation;
|
|
|
|
}
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-29 05:55:09 +01:00
|
|
|
void Renderer11::UpdateAnimation(RendererItem *item, RendererObject& obj, ANIM_FRAME** frmptr, short frac, short rate, int mask, bool useObjectWorldRotation)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2021-09-24 13:50:31 +03:00
|
|
|
static std::vector<int> boneIndexList;
|
|
|
|
boneIndexList.clear();
|
2021-09-22 12:40:57 +03:00
|
|
|
|
|
|
|
RendererBone *Bones[32] = {};
|
2020-12-21 13:16:29 -03:00
|
|
|
int nextBone = 0;
|
|
|
|
|
|
|
|
Matrix rotation;
|
|
|
|
|
|
|
|
Matrix *transforms = (item == NULL ? obj.AnimationTransforms.data() : &item->AnimationTransforms[0]);
|
|
|
|
|
|
|
|
// Push
|
|
|
|
Bones[nextBone++] = obj.Skeleton;
|
|
|
|
|
|
|
|
while (nextBone != 0)
|
|
|
|
{
|
|
|
|
// Pop the last bone in the stack
|
|
|
|
RendererBone *bone = Bones[--nextBone];
|
2021-05-18 19:16:58 -05:00
|
|
|
if (!bone) return;//otherwise inventory crashes mm
|
2020-12-21 13:16:29 -03:00
|
|
|
bool calculateMatrix = (mask >> bone->Index) & 1;
|
|
|
|
|
|
|
|
if (calculateMatrix)
|
|
|
|
{
|
|
|
|
Vector3 p = Vector3(frmptr[0]->offsetX, frmptr[0]->offsetY, frmptr[0]->offsetZ);
|
|
|
|
|
|
|
|
rotation = Matrix::CreateFromQuaternion(frmptr[0]->angles[bone->Index]);
|
2022-01-29 05:55:09 +01:00
|
|
|
//FromTrAngle(&rotation, frmptr[0], bone->Index);
|
2020-12-21 13:16:29 -03:00
|
|
|
|
|
|
|
if (frac)
|
|
|
|
{
|
|
|
|
Vector3 p2 = Vector3(frmptr[1]->offsetX, frmptr[1]->offsetY, frmptr[1]->offsetZ);
|
|
|
|
p = Vector3::Lerp(p, p2, frac / ((float)rate));
|
|
|
|
|
|
|
|
Matrix rotation2 = Matrix::CreateFromQuaternion(frmptr[1]->angles[bone->Index]);
|
2022-01-29 05:55:09 +01:00
|
|
|
//FromTrAngle(&rotation2, frmptr[1], bone->Index);
|
2020-12-21 13:16:29 -03:00
|
|
|
|
|
|
|
Quaternion q1, q2, q3;
|
|
|
|
|
|
|
|
q1 = Quaternion::CreateFromRotationMatrix(rotation);
|
|
|
|
q2 = Quaternion::CreateFromRotationMatrix(rotation2);
|
|
|
|
q3 = Quaternion::Slerp(q1, q2, frac / ((float)rate));
|
|
|
|
|
|
|
|
rotation = Matrix::CreateFromQuaternion(q3);
|
|
|
|
}
|
|
|
|
|
|
|
|
Matrix translation;
|
|
|
|
if (bone == obj.Skeleton)
|
|
|
|
translation = Matrix::CreateTranslation(p.x, p.y, p.z);
|
|
|
|
|
|
|
|
Matrix extraRotation;
|
|
|
|
extraRotation = Matrix::CreateFromYawPitchRoll(bone->ExtraRotation.y, bone->ExtraRotation.x, bone->ExtraRotation.z);
|
2021-09-22 10:48:14 +03:00
|
|
|
|
|
|
|
|
2020-12-21 13:16:29 -03:00
|
|
|
if (useObjectWorldRotation)
|
|
|
|
{
|
|
|
|
Quaternion invertedQuat;
|
2021-07-23 21:48:06 +01:00
|
|
|
auto scale = Vector3{};
|
|
|
|
auto translation = Vector3{};
|
|
|
|
transforms[bone->Parent->Index].Invert().Decompose(scale, invertedQuat, translation);
|
2021-09-17 03:46:49 +03:00
|
|
|
rotation = rotation * extraRotation * Matrix::CreateFromQuaternion(invertedQuat);
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-09-17 04:09:01 +03:00
|
|
|
rotation = extraRotation * rotation;
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bone != obj.Skeleton)
|
|
|
|
transforms[bone->Index] = rotation * bone->Transform;
|
|
|
|
else
|
|
|
|
transforms[bone->Index] = rotation * translation;
|
|
|
|
|
|
|
|
if (bone != obj.Skeleton)
|
|
|
|
|
|
|
|
transforms[bone->Index] = transforms[bone->Index] * transforms[bone->Parent->Index];
|
|
|
|
}
|
|
|
|
|
2021-09-22 12:40:57 +03:00
|
|
|
boneIndexList.push_back(bone->Index);
|
|
|
|
|
2020-12-21 13:16:29 -03:00
|
|
|
for (int i = 0; i < bone->Children.size(); i++)
|
|
|
|
{
|
|
|
|
// Push
|
|
|
|
Bones[nextBone++] = bone->Children[i];
|
|
|
|
}
|
|
|
|
}
|
2021-09-22 12:40:57 +03:00
|
|
|
|
|
|
|
// Apply mutations on top
|
2021-12-11 07:17:58 +01:00
|
|
|
if (item)
|
2021-09-22 12:40:57 +03:00
|
|
|
{
|
2022-05-05 07:08:14 +02:00
|
|
|
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
|
2021-12-11 07:17:58 +01:00
|
|
|
|
2022-03-13 02:04:24 +11:00
|
|
|
if (nativeItem->Animation.Mutator.size() == boneIndexList.size())
|
2021-09-22 12:40:57 +03:00
|
|
|
{
|
2021-12-11 07:17:58 +01:00
|
|
|
for (int i : boneIndexList)
|
|
|
|
{
|
2022-03-13 02:04:24 +11:00
|
|
|
auto mutator = nativeItem->Animation.Mutator[i];
|
2021-12-11 07:17:58 +01:00
|
|
|
if (mutator.IsEmpty())
|
|
|
|
continue;
|
2021-09-24 13:50:31 +03:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
auto m = Matrix::CreateFromYawPitchRoll(mutator.Rotation.y, mutator.Rotation.x, mutator.Rotation.z);
|
|
|
|
auto s = Matrix::CreateScale(mutator.Scale);
|
|
|
|
auto t = Matrix::CreateTranslation(mutator.Offset);
|
2021-09-24 13:50:31 +03:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
transforms[i] = m * s * t * transforms[i];
|
|
|
|
}
|
2021-09-22 12:40:57 +03:00
|
|
|
}
|
|
|
|
}
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
void Renderer11::UpdateItemAnimations(int itemNumber, bool force)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2021-12-11 07:17:58 +01:00
|
|
|
RendererItem* itemToDraw = &m_items[itemNumber];
|
2022-05-05 07:08:14 +02:00
|
|
|
ItemInfo* nativeItem = &g_Level.Items[itemNumber];
|
2021-12-11 07:17:58 +01:00
|
|
|
|
|
|
|
// TODO: hack for fixing a bug, check again if needed
|
|
|
|
itemToDraw->ItemNumber = itemNumber;
|
2020-12-21 13:16:29 -03:00
|
|
|
|
|
|
|
// Lara has her own routine
|
2022-02-09 16:55:46 +11:00
|
|
|
if (nativeItem->ObjectNumber == ID_LARA)
|
2020-12-21 13:16:29 -03:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Has been already done?
|
|
|
|
if (!force && itemToDraw->DoneAnimations)
|
|
|
|
return;
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
OBJECT_INFO* obj = &Objects[nativeItem->ObjectNumber];
|
|
|
|
RendererObject& moveableObj = *m_moveableObjects[nativeItem->ObjectNumber];
|
2020-12-21 13:16:29 -03:00
|
|
|
|
|
|
|
// Update animation matrices
|
|
|
|
if (obj->animIndex != -1 /*&& item->objectNumber != ID_HARPOON*/)
|
|
|
|
{
|
|
|
|
// Apply extra rotations
|
|
|
|
int lastJoint = 0;
|
|
|
|
for (int j = 0; j < moveableObj.LinearizedBones.size(); j++)
|
|
|
|
{
|
|
|
|
RendererBone *currentBone = moveableObj.LinearizedBones[j];
|
|
|
|
currentBone->ExtraRotation = Vector3(0.0f, 0.0f, 0.0f);
|
2021-08-30 17:50:11 +02:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
nativeItem->Data.apply(
|
2022-02-20 00:43:58 +11:00
|
|
|
[&j, ¤tBone](QuadInfo& quad)
|
|
|
|
{
|
|
|
|
if (j == 3 || j == 4)
|
|
|
|
currentBone->ExtraRotation.x = TO_RAD(quad.RearRot);
|
|
|
|
else if (j == 6 || j == 7)
|
|
|
|
currentBone->ExtraRotation.x = TO_RAD(quad.FrontRot);
|
2021-08-29 16:11:03 +02:00
|
|
|
},
|
2022-03-06 19:35:59 +11:00
|
|
|
[&j, ¤tBone](JeepInfo& jeep)
|
2022-02-20 00:43:58 +11:00
|
|
|
{
|
|
|
|
switch(j)
|
|
|
|
{
|
2021-12-11 07:17:58 +01:00
|
|
|
case 9:
|
|
|
|
currentBone->ExtraRotation.x = TO_RAD(jeep.rot1);
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
currentBone->ExtraRotation.x = TO_RAD(jeep.rot2);
|
2021-08-30 17:50:11 +02:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
currentBone->ExtraRotation.x = TO_RAD(jeep.rot3);
|
2021-08-30 17:50:11 +02:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
currentBone->ExtraRotation.x = TO_RAD(jeep.rot4);
|
2021-08-30 17:50:11 +02:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
break;
|
|
|
|
}
|
2021-08-29 16:11:03 +02:00
|
|
|
},
|
2022-03-06 19:35:59 +11:00
|
|
|
[&j, ¤tBone](MotorbikeInfo& bike)
|
2022-02-20 00:43:58 +11:00
|
|
|
{
|
|
|
|
switch (j)
|
|
|
|
{
|
2021-12-11 07:17:58 +01:00
|
|
|
case 2:
|
|
|
|
case 4:
|
|
|
|
currentBone->ExtraRotation.x = TO_RAD(bike.wheelRight);
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
currentBone->ExtraRotation.x = TO_RAD(bike.wheelLeft);
|
2022-02-20 00:43:58 +11:00
|
|
|
}
|
2021-08-29 16:11:03 +02:00
|
|
|
},
|
2022-02-22 23:22:43 +11:00
|
|
|
[&j, ¤tBone](RubberBoatInfo& boat)
|
2022-02-20 00:43:58 +11:00
|
|
|
{
|
|
|
|
if (j == 2)
|
2022-02-22 23:22:43 +11:00
|
|
|
currentBone->ExtraRotation.z = TO_RAD(boat.PropellerRotation);
|
2021-08-29 16:11:03 +02:00
|
|
|
},
|
2022-02-28 21:02:19 +11:00
|
|
|
[&j, ¤tBone](UPVInfo& upv)
|
2022-02-20 00:43:58 +11:00
|
|
|
{
|
|
|
|
if (j == 3)
|
2021-08-30 17:50:11 +02:00
|
|
|
currentBone->ExtraRotation.z = TO_RAD(upv.FanRot);
|
2021-08-29 16:11:03 +02:00
|
|
|
},
|
2022-02-20 00:43:58 +11:00
|
|
|
[&j, ¤tBone](BigGunInfo& biggun)
|
|
|
|
{
|
|
|
|
if (j == 2)
|
2022-02-23 14:40:08 +11:00
|
|
|
currentBone->ExtraRotation.z = biggun.BarrelZRotation;
|
2021-08-29 16:11:03 +02:00
|
|
|
},
|
2022-03-06 18:59:04 +11:00
|
|
|
[&j, ¤tBone, &lastJoint](CreatureInfo& creature)
|
2022-02-20 00:43:58 +11:00
|
|
|
{
|
|
|
|
if (currentBone->ExtraRotationFlags & ROT_Y)
|
|
|
|
{
|
2022-03-06 18:59:04 +11:00
|
|
|
currentBone->ExtraRotation.y = TO_RAD(creature.JointRotation[lastJoint]);
|
2021-08-30 17:50:11 +02:00
|
|
|
lastJoint++;
|
|
|
|
}
|
|
|
|
|
2022-02-20 00:43:58 +11:00
|
|
|
if (currentBone->ExtraRotationFlags & ROT_X)
|
|
|
|
{
|
2022-03-06 18:59:04 +11:00
|
|
|
currentBone->ExtraRotation.x = TO_RAD(creature.JointRotation[lastJoint]);
|
2021-08-30 17:50:11 +02:00
|
|
|
lastJoint++;
|
|
|
|
}
|
|
|
|
|
2022-02-20 00:43:58 +11:00
|
|
|
if (currentBone->ExtraRotationFlags & ROT_Z)
|
|
|
|
{
|
2022-03-06 18:59:04 +11:00
|
|
|
currentBone->ExtraRotation.z = TO_RAD(creature.JointRotation[lastJoint]);
|
2021-08-30 17:50:11 +02:00
|
|
|
lastJoint++;
|
|
|
|
}
|
|
|
|
}
|
2021-08-29 16:11:03 +02:00
|
|
|
);
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
ANIM_FRAME* framePtr[2];
|
|
|
|
int rate;
|
2021-12-11 07:17:58 +01:00
|
|
|
int frac = GetFrame(nativeItem, framePtr, &rate);
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2022-01-29 05:55:09 +01:00
|
|
|
UpdateAnimation(itemToDraw, moveableObj, framePtr, frac, rate, 0xFFFFFFFF);
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
for (int m = 0; m < obj->nmeshes; m++)
|
2020-12-21 13:16:29 -03:00
|
|
|
itemToDraw->AnimationTransforms[m] = itemToDraw->AnimationTransforms[m];
|
|
|
|
}
|
|
|
|
|
|
|
|
itemToDraw->DoneAnimations = true;
|
|
|
|
}
|
|
|
|
|
2022-02-20 00:43:58 +11:00
|
|
|
void Renderer11::UpdateItemsAnimations(RenderView& view)
|
|
|
|
{
|
2020-12-21 13:16:29 -03:00
|
|
|
Matrix translation;
|
|
|
|
Matrix rotation;
|
|
|
|
|
2021-12-09 11:34:58 +01:00
|
|
|
for (auto room : view.roomsToDraw)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2021-12-09 11:34:58 +01:00
|
|
|
for (auto itemToDraw : room->ItemsToDraw)
|
|
|
|
{
|
2022-05-05 07:08:14 +02:00
|
|
|
ItemInfo* nativeItem = &g_Level.Items[itemToDraw->ItemNumber];
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2021-12-09 11:34:58 +01:00
|
|
|
// Lara has her own routine
|
2022-02-09 16:55:46 +11:00
|
|
|
if (nativeItem->ObjectNumber == ID_LARA)
|
2021-12-09 11:34:58 +01:00
|
|
|
continue;
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
UpdateItemAnimations(itemToDraw->ItemNumber, false);
|
2021-12-09 11:34:58 +01:00
|
|
|
}
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-20 00:43:58 +11:00
|
|
|
void Renderer11::FromTrAngle(Matrix *matrix, short *frameptr, int index)
|
|
|
|
{
|
2020-12-21 13:16:29 -03:00
|
|
|
short *ptr = &frameptr[0];
|
|
|
|
|
|
|
|
ptr += 9;
|
|
|
|
for (int i = 0; i < index; i++)
|
|
|
|
ptr += ((*ptr & 0xc000) == 0 ? 2 : 1);
|
|
|
|
|
|
|
|
int rot0 = *ptr++;
|
|
|
|
int frameMode = (rot0 & 0xc000);
|
|
|
|
|
|
|
|
int rot1;
|
|
|
|
int rotX;
|
|
|
|
int rotY;
|
|
|
|
int rotZ;
|
|
|
|
|
|
|
|
switch (frameMode)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
rot1 = *ptr++;
|
|
|
|
rotX = ((rot0 & 0x3ff0) >> 4);
|
|
|
|
rotY = (((rot1 & 0xfc00) >> 10) | ((rot0 & 0xf) << 6) & 0x3ff);
|
|
|
|
rotZ = ((rot1)&0x3ff);
|
|
|
|
|
|
|
|
*matrix = Matrix::CreateFromYawPitchRoll(rotY * (360.0f / 1024.0f) * RADIAN,
|
|
|
|
rotX * (360.0f / 1024.0f) * RADIAN,
|
|
|
|
rotZ * (360.0f / 1024.0f) * RADIAN);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x4000:
|
|
|
|
*matrix = Matrix::CreateRotationX((rot0 & 0xfff) * (360.0f / 4096.0f) * RADIAN);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x8000:
|
|
|
|
*matrix = Matrix::CreateRotationY((rot0 & 0xfff) * (360.0f / 4096.0f) * RADIAN);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xc000:
|
|
|
|
*matrix = Matrix::CreateRotationZ((rot0 & 0xfff) * (360.0f / 4096.0f) * RADIAN);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-29 05:55:09 +01:00
|
|
|
void Renderer11::BuildHierarchyRecursive(RendererObject *obj, RendererBone *node, RendererBone *parentNode) {
|
2020-12-21 13:16:29 -03:00
|
|
|
node->GlobalTransform = node->Transform * parentNode->GlobalTransform;
|
|
|
|
obj->BindPoseTransforms[node->Index] = node->GlobalTransform;
|
|
|
|
obj->Skeleton->GlobalTranslation = Vector3(0.0f, 0.0f, 0.0f);
|
|
|
|
node->GlobalTranslation = node->Translation + parentNode->GlobalTranslation;
|
|
|
|
|
|
|
|
for (int j = 0; j < node->Children.size(); j++)
|
|
|
|
{
|
2022-01-29 05:55:09 +01:00
|
|
|
BuildHierarchyRecursive(obj, node->Children[j], node);
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-29 05:55:09 +01:00
|
|
|
void Renderer11::BuildHierarchy(RendererObject *obj) {
|
2020-12-21 13:16:29 -03:00
|
|
|
obj->Skeleton->GlobalTransform = obj->Skeleton->Transform;
|
|
|
|
obj->BindPoseTransforms[obj->Skeleton->Index] = obj->Skeleton->GlobalTransform;
|
|
|
|
obj->Skeleton->GlobalTranslation = Vector3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
for (int j = 0; j < obj->Skeleton->Children.size(); j++)
|
|
|
|
{
|
2022-01-29 05:55:09 +01:00
|
|
|
BuildHierarchyRecursive(obj, obj->Skeleton->Children[j], obj->Skeleton);
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
bool Renderer11::IsFullsScreen() {
|
2020-12-21 13:16:29 -03:00
|
|
|
return (!Windowed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Renderer11::UpdateCameraMatrices(CAMERA_INFO *cam, float roll, float fov)
|
|
|
|
{
|
|
|
|
gameCamera = RenderView(cam, roll, fov, 32, 102400, g_Configuration.Width, g_Configuration.Height);
|
|
|
|
}
|
|
|
|
|
2022-01-29 05:55:09 +01:00
|
|
|
bool Renderer11::SphereBoxIntersection(Vector3 boxMin, Vector3 boxMax, Vector3 sphereCentre, float sphereRadius)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
|
|
|
Vector3 centre = (boxMin + boxMax) / 2.0f;
|
|
|
|
Vector3 extens = boxMax - centre;
|
|
|
|
BoundingBox box = BoundingBox(centre, extens);
|
|
|
|
BoundingSphere sphere = BoundingSphere(sphereCentre, sphereRadius);
|
|
|
|
return box.Intersects(sphere);
|
|
|
|
}
|
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
void Renderer11::GetLaraBonePosition(Vector3 *pos, int bone) {}
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
void Renderer11::FlipRooms(short roomNumber1, short roomNumber2)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2021-12-09 06:33:19 +01:00
|
|
|
std::swap(m_rooms[roomNumber1], m_rooms[roomNumber2]);
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2021-12-09 11:17:56 +01:00
|
|
|
m_rooms[roomNumber1].RoomNumber = roomNumber1;
|
|
|
|
m_rooms[roomNumber2].RoomNumber = roomNumber2;
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
|
2022-02-02 05:10:16 +01:00
|
|
|
RendererMesh* Renderer11::GetMesh(int meshIndex)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
|
|
|
return m_meshes[meshIndex];
|
|
|
|
}
|
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
void Renderer11::GetLaraAbsBonePosition(Vector3 *pos, int joint)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
|
|
|
Matrix world = m_moveableObjects[ID_LARA]->AnimationTransforms[joint];
|
|
|
|
world = world * m_LaraWorldMatrix;
|
|
|
|
*pos = Vector3::Transform(*pos, world);
|
|
|
|
}
|
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
void Renderer11::GetItemAbsBonePosition(int itemNumber, Vector3 *pos, int joint)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
|
|
|
RendererItem *rendererItem = &m_items[itemNumber];
|
2022-05-05 07:08:14 +02:00
|
|
|
ItemInfo* nativeItem = &g_Level.Items[itemNumber];
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
rendererItem->ItemNumber = itemNumber;
|
|
|
|
|
|
|
|
if (!rendererItem)
|
2020-12-21 13:16:29 -03:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!rendererItem->DoneAnimations)
|
|
|
|
{
|
2022-02-12 16:25:59 +11:00
|
|
|
if (itemNumber == Lara.ItemNumber)
|
2022-02-03 05:20:13 +01:00
|
|
|
UpdateLaraAnimations(false);
|
2020-12-21 13:16:29 -03:00
|
|
|
else
|
2022-02-03 05:20:13 +01:00
|
|
|
UpdateItemAnimations(itemNumber, false);
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
Matrix world = rendererItem->AnimationTransforms[joint] * rendererItem->World;
|
|
|
|
*pos = Vector3::Transform(*pos, world);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Renderer11::getSpheres(short itemNumber, BoundingSphere *spheres, char worldSpace, Matrix local)
|
|
|
|
{
|
2021-12-11 07:17:58 +01:00
|
|
|
RendererItem* itemToDraw = &m_items[itemNumber];
|
2022-05-05 07:08:14 +02:00
|
|
|
ItemInfo* nativeItem = &g_Level.Items[itemNumber];
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
itemToDraw->ItemNumber = itemNumber;
|
|
|
|
|
|
|
|
if (!nativeItem)
|
2020-12-21 13:16:29 -03:00
|
|
|
return 0;
|
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
if (!itemToDraw->DoneAnimations)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2022-02-12 16:25:59 +11:00
|
|
|
if (itemNumber == Lara.ItemNumber)
|
2022-02-03 05:20:13 +01:00
|
|
|
UpdateLaraAnimations(false);
|
2020-12-21 13:16:29 -03:00
|
|
|
else
|
2022-02-03 05:20:13 +01:00
|
|
|
UpdateItemAnimations(itemNumber, false);
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
Matrix world;
|
|
|
|
|
|
|
|
if (worldSpace & SPHERES_SPACE_WORLD)
|
2022-03-31 23:55:54 +11:00
|
|
|
world = Matrix::CreateTranslation(nativeItem->Pose.Position.x, nativeItem->Pose.Position.y, nativeItem->Pose.Position.z) * local;
|
2021-08-03 13:23:51 +03:00
|
|
|
else
|
|
|
|
world = Matrix::Identity * local;
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2022-03-31 23:55:54 +11:00
|
|
|
world = Matrix::CreateFromYawPitchRoll(TO_RAD(nativeItem->Pose.Orientation.y), TO_RAD(nativeItem->Pose.Orientation.x), TO_RAD(nativeItem->Pose.Orientation.z)) * world;
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
short objNum = nativeItem->ObjectNumber;
|
2021-06-04 06:02:19 +02:00
|
|
|
if (objNum == ID_LARA) objNum = ID_LARA_SKIN;
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
RendererObject& moveable = *m_moveableObjects[objNum];
|
|
|
|
|
|
|
|
for (int i = 0; i< moveable.ObjectMeshes.size();i++)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2021-12-11 07:17:58 +01:00
|
|
|
auto mesh = moveable.ObjectMeshes[i];
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2021-08-05 13:31:42 +03:00
|
|
|
Vector3 pos = mesh->Sphere.Center;
|
2020-12-21 13:16:29 -03:00
|
|
|
if (worldSpace & SPHERES_SPACE_BONE_ORIGIN)
|
2021-08-05 13:31:42 +03:00
|
|
|
pos += moveable.LinearizedBones[i]->Translation;
|
2020-12-21 13:16:29 -03:00
|
|
|
|
2021-12-11 07:17:58 +01:00
|
|
|
spheres[i].Center = Vector3::Transform(pos, (itemToDraw->AnimationTransforms[i] * world));
|
2020-12-21 13:16:29 -03:00
|
|
|
spheres[i].Radius = mesh->Sphere.Radius;
|
2021-08-05 13:31:42 +03:00
|
|
|
|
|
|
|
// Spheres debug
|
|
|
|
// auto v1 = Vector3(spheres[i].Center.x - spheres[i].Radius, spheres[i].Center.y, spheres[i].Center.z);
|
|
|
|
// auto v2 = Vector3(spheres[i].Center.x + spheres[i].Radius, spheres[i].Center.y, spheres[i].Center.z);
|
2022-02-03 05:20:13 +01:00
|
|
|
// AddLine3D(v1, v2, Vector4::One);
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
return moveable.ObjectMeshes.size();
|
|
|
|
}
|
|
|
|
|
2022-02-03 05:20:13 +01:00
|
|
|
void Renderer11::GetBoneMatrix(short itemNumber, int joint, Matrix *outMatrix)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
2022-02-12 16:25:59 +11:00
|
|
|
if (itemNumber == Lara.ItemNumber)
|
2020-12-21 13:16:29 -03:00
|
|
|
{
|
|
|
|
RendererObject& obj = *m_moveableObjects[ID_LARA];
|
|
|
|
*outMatrix = obj.AnimationTransforms[joint] * m_LaraWorldMatrix;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-03 05:20:13 +01:00
|
|
|
UpdateItemAnimations(itemNumber, true);
|
2021-12-11 07:17:58 +01:00
|
|
|
|
|
|
|
RendererItem* rendererItem = &m_items[itemNumber];
|
2022-05-05 07:08:14 +02:00
|
|
|
ItemInfo* nativeItem = &g_Level.Items[itemNumber];
|
2021-12-11 07:17:58 +01:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
RendererObject& obj = *m_moveableObjects[nativeItem->ObjectNumber];
|
2021-12-11 07:17:58 +01:00
|
|
|
*outMatrix = obj.AnimationTransforms[joint] * rendererItem->World;
|
2020-12-21 13:16:29 -03:00
|
|
|
}
|
|
|
|
}
|
2022-04-09 06:22:29 +02:00
|
|
|
|
|
|
|
Vector4 Renderer11::GetPortalRect(Vector4 v, Vector4 vp)
|
|
|
|
{
|
|
|
|
Vector4 sp = (v * Vector4(0.5f, 0.5f, 0.5f, 0.5f)
|
|
|
|
+ Vector4(0.5f, 0.5f, 0.5f, 0.5f))
|
|
|
|
* Vector4(vp.z, vp.w, vp.z, vp.w);
|
|
|
|
|
|
|
|
Vector4 s(sp.x + vp.x, sp.y + vp.y, sp.z + vp.x, sp.w + vp.y);
|
|
|
|
|
|
|
|
// expand
|
|
|
|
s.x -= 2;
|
|
|
|
s.y -= 2;
|
|
|
|
s.z += 2;
|
|
|
|
s.w += 2;
|
|
|
|
|
|
|
|
// clamp
|
|
|
|
s.x = std::max(s.x, vp.x);
|
|
|
|
s.y = std::max(s.y, vp.y);
|
|
|
|
s.z = std::min(s.z, vp.x + vp.z);
|
|
|
|
s.w = std::min(s.w, vp.y + vp.w);
|
|
|
|
|
|
|
|
// convert from bounds to x,y,w,h
|
|
|
|
s.z -= s.x;
|
|
|
|
s.w -= s.y;
|
|
|
|
|
|
|
|
// Use the viewport rect if one of the dimensions is the same size
|
|
|
|
// as the viewport. This may fix clipping bugs while still allowing
|
|
|
|
// impossible geometry tricks.
|
|
|
|
if (s.z - s.x >= vp.z - vp.x || s.w - s.y >= vp.w - vp.y)
|
|
|
|
{
|
|
|
|
return vp;
|
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
2021-12-11 07:17:58 +01:00
|
|
|
}
|