TombEngine/TR5Main/Renderer/Renderer11Helper.cpp

758 lines
21 KiB
C++
Raw Normal View History

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"
2021-12-24 03:32:19 +03:00
#include "Scripting/GameFlowScript.h"
#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;
extern GameFlow *g_GameFlow;
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
{
return (g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER);
2020-12-21 13:16:29 -03:00
}
bool Renderer11::isInRoom(int x, int y, int z, short roomNumber)
{
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
}
2021-08-30 18:03:21 +03: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
{
for (auto room : view.roomsToDraw)
2020-12-21 13:16:29 -03:00
{
for (auto fx : room->EffectsToDraw)
{
Matrix translation = Matrix::CreateTranslation(fx->Effect->pos.xPos, fx->Effect->pos.yPos, fx->Effect->pos.zPos);
Matrix rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(fx->Effect->pos.yRot), TO_RAD(fx->Effect->pos.xRot), TO_RAD(fx->Effect->pos.zRot));
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;
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
if (item)
2021-09-22 12:40:57 +03:00
{
ITEM_INFO* nativeItem = &g_Level.Items[item->ItemNumber];
if (nativeItem->Mutator.size() == boneIndexList.size())
2021-09-22 12:40:57 +03:00
{
for (int i : boneIndexList)
{
auto mutator = nativeItem->Mutator[i];
if (mutator.IsEmpty())
continue;
2021-09-24 13:50:31 +03: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
transforms[i] = m * s * t * transforms[i];
}
2021-09-22 12:40:57 +03:00
}
}
2020-12-21 13:16:29 -03:00
}
void Renderer11::updateItemAnimations(int itemNumber, bool force)
{
RendererItem* itemToDraw = &m_items[itemNumber];
ITEM_INFO* nativeItem = &g_Level.Items[itemNumber];
// 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
if (nativeItem->ObjectNumber == ID_LARA)
2020-12-21 13:16:29 -03:00
return;
// Has been already done?
if (!force && itemToDraw->DoneAnimations)
return;
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);
nativeItem->Data.apply(
2022-02-20 00:43:58 +11:00
[&j, &currentBone](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);
},
2022-02-20 00:43:58 +11:00
[&j, &currentBone](JEEP_INFO& jeep)
{
switch(j)
{
case 9:
currentBone->ExtraRotation.x = TO_RAD(jeep.rot1);
break;
case 10:
currentBone->ExtraRotation.x = TO_RAD(jeep.rot2);
break;
case 12:
currentBone->ExtraRotation.x = TO_RAD(jeep.rot3);
break;
case 13:
currentBone->ExtraRotation.x = TO_RAD(jeep.rot4);
break;
}
},
2022-02-20 00:43:58 +11:00
[&j, &currentBone](MOTORBIKE_INFO& bike)
{
switch (j)
{
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
}
},
2022-02-22 23:22:43 +11:00
[&j, &currentBone](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);
},
2022-02-28 21:02:19 +11:00
[&j, &currentBone](UPVInfo& upv)
2022-02-20 00:43:58 +11:00
{
if (j == 3)
currentBone->ExtraRotation.z = TO_RAD(upv.FanRot);
},
2022-02-20 00:43:58 +11:00
[&j, &currentBone](BigGunInfo& biggun)
{
if (j == 2)
2022-02-23 14:40:08 +11:00
currentBone->ExtraRotation.z = biggun.BarrelZRotation;
},
2022-02-20 00:43:58 +11:00
[&j, &currentBone, &lastJoint](CREATURE_INFO& creature)
{
if (currentBone->ExtraRotationFlags & ROT_Y)
{
currentBone->ExtraRotation.y = TO_RAD(creature.jointRotation[lastJoint]);
lastJoint++;
}
2022-02-20 00:43:58 +11:00
if (currentBone->ExtraRotationFlags & ROT_X)
{
currentBone->ExtraRotation.x = TO_RAD(creature.jointRotation[lastJoint]);
lastJoint++;
}
2022-02-20 00:43:58 +11:00
if (currentBone->ExtraRotationFlags & ROT_Z)
{
currentBone->ExtraRotation.z = TO_RAD(creature.jointRotation[lastJoint]);
lastJoint++;
}
}
);
2020-12-21 13:16:29 -03:00
}
ANIM_FRAME* framePtr[2];
int rate;
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
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;
for (auto room : view.roomsToDraw)
2020-12-21 13:16:29 -03:00
{
for (auto itemToDraw : room->ItemsToDraw)
{
ITEM_INFO* nativeItem = &g_Level.Items[itemToDraw->ItemNumber];
2020-12-21 13:16:29 -03:00
// Lara has her own routine
if (nativeItem->ObjectNumber == ID_LARA)
continue;
2020-12-21 13:16:29 -03:00
updateItemAnimations(itemToDraw->ItemNumber, false);
}
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
}
}
bool Renderer11::isFullsScreen() {
2020-12-21 13:16:29 -03:00
return (!Windowed);
}
bool Renderer11::isFading()
{
return false;
return (m_fadeStatus != RENDERER_FADE_STATUS::NO_FADE);
}
void Renderer11::UpdateCameraMatrices(CAMERA_INFO *cam, float roll, float fov)
{
gameCamera = RenderView(cam, roll, fov, 32, 102400, g_Configuration.Width, g_Configuration.Height);
}
void Renderer11::EnumerateVideoModes()
{
HRESULT res;
IDXGIFactory *dxgiFactory = NULL;
Utils::throwIfFailed(CreateDXGIFactory(__uuidof(IDXGIFactory), (void **)&dxgiFactory));
IDXGIAdapter *dxgiAdapter = NULL;
for (int i = 0; dxgiFactory->EnumAdapters(i, &dxgiAdapter) != DXGI_ERROR_NOT_FOUND; i++)
{
DXGI_ADAPTER_DESC adapterDesc;
UINT stringLength;
char videoCardDescription[128];
dxgiAdapter->GetDesc(&adapterDesc);
int error = wcstombs_s(&stringLength, videoCardDescription, 128, adapterDesc.Description, 128);
RendererVideoAdapter adapter;
adapter.Index = i;
adapter.Name = videoCardDescription;
TENLog("Adapter " + std::to_string(i), LogLevel::Info);
TENLog("Device Name: " + adapter.Name, LogLevel::Info);
2020-12-21 13:16:29 -03:00
ComPtr<IDXGIOutput> output;
if(FAILED(dxgiAdapter->EnumOutputs(0, output.GetAddressOf())))
continue;
UINT numModes = 0;
std::vector<DXGI_MODE_DESC> displayModes;
DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
// Get the number of elements
Utils::throwIfFailed(output->GetDisplayModeList(format, 0, &numModes, NULL));
// Get the list
displayModes.resize(numModes);
Utils::throwIfFailed(output->GetDisplayModeList(format, 0, &numModes, displayModes.data()));
for (int j = 0; j < numModes; j++)
{
DXGI_MODE_DESC *mode = &displayModes[j];
RendererDisplayMode newMode;
// discard lower resolutions
if (mode->Width < 1024 || mode->Height < 768)
continue;
newMode.Width = mode->Width;
newMode.Height = mode->Height;
newMode.RefreshRate = mode->RefreshRate.Numerator / mode->RefreshRate.Denominator;
bool found = false;
for (int k = 0; k < adapter.DisplayModes.size(); k++)
{
RendererDisplayMode *currentMode = &adapter.DisplayModes[k];
if (currentMode->Width == newMode.Width && currentMode->Height == newMode.Height &&
currentMode->RefreshRate == newMode.RefreshRate)
{
found = true;
break;
}
}
if (found)
continue;
adapter.DisplayModes.push_back(newMode);
}
m_adapters.push_back(adapter);
}
dxgiFactory->Release();
}
2022-01-29 05:55:09 +01:00
void Renderer11::GetVisibleObjects(int from, int to, RenderView& renderView, bool onlyRooms)
2020-12-21 13:16:29 -03:00
{
// Avoid allocations, 1024 should be fine
RendererRoomNode nodes[512];
int nextNode = 0;
// Avoid reallocations, 1024 should be fine
RendererRoomNode *stack[512];
int stackDepth = 0;
RendererRoomNode *node = &nodes[nextNode++];
node->To = to;
node->From = -1;
// Push
stack[stackDepth++] = node;
while (stackDepth > 0)
{
// Pop
node = stack[--stackDepth];
if (m_rooms[node->To].Visited)
2020-12-21 13:16:29 -03:00
continue;
ROOM_INFO *room = &g_Level.Rooms[node->To];
Vector3 roomCentre = Vector3(room->x + room->xSize * WALL_SIZE / 2.0f,
(room->minfloor + room->maxceiling) / 2.0f,
2021-11-08 17:28:04 +03:00
room->z + room->zSize * WALL_SIZE / 2.0f);
2020-12-21 13:16:29 -03:00
Vector3 laraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
m_rooms[node->To].Distance = (roomCentre - laraPosition).Length();
m_rooms[node->To].Visited = true;
2020-12-21 13:16:29 -03:00
renderView.roomsToDraw.push_back(&m_rooms[node->To]);
g_Level.Rooms[node->To].boundActive = true;
if (!onlyRooms)
{
2022-01-29 05:55:09 +01:00
CollectLightsForRoom(node->To, renderView);
CollectItems(node->To, renderView);
CollectStatics(node->To, renderView);
CollectEffects(node->To, renderView);
}
2020-12-21 13:16:29 -03:00
Vector4 clipPort;
for (int i = 0; i < room->doors.size(); i++)
{
short adjoiningRoom = room->doors[i].room;
2022-01-29 05:55:09 +01:00
if (node->From != adjoiningRoom && CheckPortal(node->To, &room->doors[i], renderView.camera.ViewProjection))
2020-12-21 13:16:29 -03:00
{
RendererRoomNode *childNode = &nodes[nextNode++];
childNode->From = node->To;
childNode->To = adjoiningRoom;
// Push
stack[stackDepth++] = childNode;
}
}
}
}
2022-01-29 05:55:09 +01:00
bool Renderer11::CheckPortal(short roomIndex, ROOM_DOOR* portal, const Matrix& viewProjection)
2020-12-21 13:16:29 -03:00
{
ROOM_INFO *room = &g_Level.Rooms[roomIndex];
Vector3 n = portal->normal;
Vector3 v = Vector3(
Camera.pos.x - (room->x + portal->vertices[0].x),
Camera.pos.y - (room->y + portal->vertices[0].y),
Camera.pos.z - (room->z + portal->vertices[0].z));
// Test camera and normal positions and decide if process door or not
if (n.Dot(v) <= 0.0f)
return false;
int zClip = 0;
Vector4 p[4];
Vector4 clipPort{ FLT_MAX ,FLT_MAX ,FLT_MIN,FLT_MIN };
// Project all portal's corners in screen space
for (int i = 0; i < 4; i++)
{
Vector4 tmp = Vector4(portal->vertices[i].x + room->x, portal->vertices[i].y + room->y, portal->vertices[i].z + room->z, 1.0f);
// Project corner on screen
Vector4::Transform(tmp, viewProjection, p[i]);
if (p[i].w > 0.0f)
{
// The corner is in front of camera
p[i].x *= (1.0f / p[i].w);
p[i].y *= (1.0f / p[i].w);
p[i].z *= (1.0f / p[i].w);
clipPort.x = std::min(clipPort.x, p[i].x);
clipPort.y = std::min(clipPort.y, p[i].y);
clipPort.z = std::max(clipPort.z, p[i].x);
clipPort.w = std::max(clipPort.w, p[i].y);
}
else
// The corner is behind camera
zClip++;
}
// If all points are behind camera then door is not visible
if (zClip == 4)
return false;
// If door crosses camera plane...
if (zClip > 0)
{
for (int i = 0; i < 4; i++)
{
Vector4 a = p[i];
Vector4 b = p[(i + 1) % 4];
if ((a.w > 0.0f) ^ (b.w > 0.0f))
{
if (a.x < 0.0f && b.x < 0.0f)
clipPort.x = -1.0f;
else if (a.x > 0.0f && b.x > 0.0f)
clipPort.z = 1.0f;
else
{
clipPort.x = -1.0f;
clipPort.z = 1.0f;
}
if (a.y < 0.0f && b.y < 0.0f)
clipPort.y = -1.0f;
else if (a.y > 0.0f && b.y > 0.0f)
clipPort.w = 1.0f;
else
{
clipPort.y = -1.0f;
clipPort.w = 1.0f;
}
}
}
}
Vector4 vp = Vector4(-1.0f, -1.0f, 1.0f, 1.0f);
clipPort.x = std::max(clipPort.x, vp.x);
clipPort.y = std::max(clipPort.y, vp.y);
clipPort.z = std::min(clipPort.z, vp.z);
clipPort.w = std::min(clipPort.w, vp.w);
if (clipPort.x > vp.z || clipPort.y > vp.w || clipPort.z < vp.x || clipPort.w < vp.y)
return false;
return true;
}
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);
}
void Renderer11::getLaraBonePosition(Vector3 *pos, int bone) {}
void Renderer11::flipRooms(short roomNumber1, short roomNumber2)
{
std::swap(m_rooms[roomNumber1], m_rooms[roomNumber2]);
2020-12-21 13:16:29 -03: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];
}
void Renderer11::getLaraAbsBonePosition(Vector3 *pos, int joint)
{
Matrix world = m_moveableObjects[ID_LARA]->AnimationTransforms[joint];
world = world * m_LaraWorldMatrix;
*pos = Vector3::Transform(*pos, world);
}
void Renderer11::getItemAbsBonePosition(int itemNumber, Vector3 *pos, int joint)
{
RendererItem *rendererItem = &m_items[itemNumber];
ITEM_INFO* nativeItem = &g_Level.Items[itemNumber];
2020-12-21 13:16:29 -03: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)
2020-12-21 13:16:29 -03:00
updateLaraAnimations(false);
else
updateItemAnimations(itemNumber, false);
}
Matrix world = rendererItem->AnimationTransforms[joint] * rendererItem->World;
*pos = Vector3::Transform(*pos, world);
}
int Renderer11::getSpheres(short itemNumber, BoundingSphere *spheres, char worldSpace, Matrix local)
{
RendererItem* itemToDraw = &m_items[itemNumber];
ITEM_INFO* nativeItem = &g_Level.Items[itemNumber];
2020-12-21 13:16:29 -03:00
itemToDraw->ItemNumber = itemNumber;
if (!nativeItem)
2020-12-21 13:16:29 -03:00
return 0;
if (!itemToDraw->DoneAnimations)
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
updateLaraAnimations(false);
else
updateItemAnimations(itemNumber, false);
}
Matrix world;
if (worldSpace & SPHERES_SPACE_WORLD)
world = Matrix::CreateTranslation(nativeItem->Position.xPos, nativeItem->Position.yPos, nativeItem->Position.zPos) * local;
else
world = Matrix::Identity * local;
2020-12-21 13:16:29 -03:00
world = Matrix::CreateFromYawPitchRoll(TO_RAD(nativeItem->Position.yRot), TO_RAD(nativeItem->Position.xRot), TO_RAD(nativeItem->Position.zRot)) * world;
2020-12-21 13:16:29 -03:00
short objNum = nativeItem->ObjectNumber;
if (objNum == ID_LARA) objNum = ID_LARA_SKIN;
2020-12-21 13:16:29 -03:00
RendererObject& moveable = *m_moveableObjects[objNum];
for (int i = 0; i< moveable.ObjectMeshes.size();i++)
2020-12-21 13:16:29 -03:00
{
auto mesh = moveable.ObjectMeshes[i];
2020-12-21 13:16:29 -03:00
Vector3 pos = mesh->Sphere.Center;
2020-12-21 13:16:29 -03:00
if (worldSpace & SPHERES_SPACE_BONE_ORIGIN)
pos += moveable.LinearizedBones[i]->Translation;
2020-12-21 13:16:29 -03: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;
// 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);
// addLine3D(v1, v2, Vector4::One);
2020-12-21 13:16:29 -03:00
}
return moveable.ObjectMeshes.size();
}
void Renderer11::getBoneMatrix(short itemNumber, int joint, Matrix *outMatrix)
{
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
{
updateItemAnimations(itemNumber, true);
RendererItem* rendererItem = &m_items[itemNumber];
ITEM_INFO* nativeItem = &g_Level.Items[itemNumber];
RendererObject& obj = *m_moveableObjects[nativeItem->ObjectNumber];
*outMatrix = obj.AnimationTransforms[joint] * rendererItem->World;
2020-12-21 13:16:29 -03:00
}
}
}