This commit is contained in:
Lwmte 2025-04-25 09:20:23 +02:00
parent c1eb5b141e
commit a826c8b74f
14 changed files with 51 additions and 43 deletions

View file

@ -10,8 +10,6 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Added muzzle glow effect for firearms.
### Bug fixes
* Fixed crashes when shooting, if gunflash or gunshell objects are not present in a level.
* Fixed crashes when Lara is on a vehicle unreachable by friendly NPCs.
* Fixed Teleporter object.
* Fixed Wraith objects not working correctly in flipped rooms.
* Fixed lensflare enabled status not saved in a savegame.
@ -22,6 +20,9 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Fixed caustics not rendered correctly if texture compression was enabled.
* Fixed exclusion blend mode not working correctly.
* Fixed SSAO incorrectly applied through alpha blended textures.
* Fixed static meshes not interpolating when dynamically changing their positional data.
* Fixed crashes when shooting, if gunflash or gunshell objects are not present in a level.
* Fixed crashes when Lara is on a vehicle unreachable by friendly NPCs.
* Removed legacy TR5 search object code which caused issues with meshswaps.
### Lua API changes

View file

@ -61,7 +61,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe
{
int meshIndex = 0;
short yRot = 0;
float scale;
Vector3 scale;
Vector3 pos;
bool isStatic;
@ -74,7 +74,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe
meshIndex = Statics[mesh->staticNumber].meshNumber;
yRot = mesh->pos.Orientation.y;
pos = Vector3(mesh->pos.Position.x, mesh->pos.Position.y, mesh->pos.Position.z);
scale = mesh->scale;
scale = mesh->pos.Scale;
if (mesh->HitPoints <= 0)
mesh->flags &= ~StaticMeshFlags::SM_VISIBLE;
@ -89,7 +89,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe
meshIndex = item->meshIndex;
yRot = item->yRot;
pos = item->sphere.Center;
scale = 1.0f;
scale = Vector3::One;
}
auto fragmentsMesh = &g_Level.Meshes[meshIndex];

View file

@ -255,11 +255,11 @@ GameBoundingBox& GetBoundsAccurate(const MESH_INFO& mesh, bool getVisibilityBox)
if (getVisibilityBox)
{
bounds = Statics[mesh.staticNumber].visibilityBox * mesh.scale;
bounds = Statics[mesh.staticNumber].visibilityBox * mesh.pos.Scale;
}
else
{
bounds = Statics[mesh.staticNumber].collisionBox * mesh.scale;
bounds = Statics[mesh.staticNumber].collisionBox * mesh.pos.Scale;
}
return bounds;

View file

@ -77,7 +77,6 @@ struct MESH_INFO
{
Pose pos;
int roomNumber;
float scale;
short staticNumber;
short flags;
Vector4 color;

View file

@ -1081,7 +1081,6 @@ const std::vector<byte> SaveGame::Build()
Save::StaticMeshInfoBuilder staticMesh{ fbb };
staticMesh.add_pose(&FromPose(room->mesh[j].pos));
staticMesh.add_scale(room->mesh[j].scale);
staticMesh.add_color(&FromVector4(room->mesh[j].color));
staticMesh.add_flags(room->mesh[j].flags);
@ -2516,7 +2515,6 @@ static void ParseLevel(const Save::SaveGame* s, bool hubMode)
room->mesh[number].pos = ToPose(*staticMesh->pose());
room->mesh[number].roomNumber = staticMesh->room_number();
room->mesh[number].scale = staticMesh->scale();
room->mesh[number].color = ToVector4(staticMesh->color());
room->mesh[number].flags = staticMesh->flags();

View file

@ -167,6 +167,14 @@
Z1 * scalar, Z2 * scalar);
}
GameBoundingBox GameBoundingBox::operator *(Vector3 scalar) const
{
return GameBoundingBox(
X1 * scalar.x, X2 * scalar.x,
Y1 * scalar.y, Y2 * scalar.y,
Z1 * scalar.z, Z2 * scalar.z);
}
GameBoundingBox GameBoundingBox::operator /(float scalar) const
{
return GameBoundingBox(
@ -174,4 +182,12 @@
Y1 / scalar, Y2 / scalar,
Z1 / scalar, Z2 / scalar);
}
GameBoundingBox GameBoundingBox::operator /(Vector3 scalar) const
{
return GameBoundingBox(
X1 / scalar.x, X2 / scalar.x,
Y1 / scalar.y, Y2 / scalar.y,
Z1 / scalar.z, Z2 / scalar.z);
}
//}

View file

@ -57,6 +57,8 @@ struct ObjectInfo;
GameBoundingBox operator -(const GameBoundingBox& bounds) const;
GameBoundingBox operator -(const Pose& pose) const;
GameBoundingBox operator *(float scalar) const;
GameBoundingBox operator *(Vector3 scalar) const;
GameBoundingBox operator /(float scalar) const;
GameBoundingBox operator /(Vector3 scalar) const;
};
//}

View file

@ -292,12 +292,11 @@ namespace TEN::Renderer
staticInfo->RoomNumber = oldMesh->roomNumber;
staticInfo->Color = oldMesh->color;
staticInfo->AmbientLight = r->AmbientLight;
staticInfo->Pose = oldMesh->pos;
staticInfo->Scale = oldMesh->scale;
staticInfo->Pose = staticInfo->PrevPose = oldMesh->pos;
staticInfo->OriginalSphere = Statics[staticInfo->ObjectNumber].visibilityBox.ToLocalBoundingSphere();
staticInfo->IndexInRoom = l;
staticInfo->Update();
staticInfo->Update(GetInterpolationFactor());
}
}

View file

@ -527,10 +527,9 @@ namespace TEN::Renderer
mesh->Color = nativeMesh->color;
mesh->OriginalSphere = Statics[mesh->ObjectNumber].visibilityBox.ToLocalBoundingSphere();
mesh->Pose = nativeMesh->pos;
mesh->Scale = nativeMesh->scale;
mesh->Update();
mesh->Update(GetInterpolationFactor());
nativeMesh->Dirty = false;
nativeMesh->Dirty = (mesh->PrevPose != mesh->Pose);
}
if (!(nativeMesh->flags & StaticMeshFlags::SM_VISIBLE))
@ -931,5 +930,11 @@ namespace TEN::Renderer
effect.PrevRotation = effect.Rotation;
effect.PrevScale = effect.Scale;
}
for (auto& room : _rooms)
{
for (auto& stat : room.Statics)
stat.PrevPose = stat.Pose;
}
}
}

View file

@ -15,6 +15,7 @@ namespace TEN::Renderer::Structures
int ObjectNumber;
int RoomNumber;
int IndexInRoom;
Pose PrevPose;
Pose Pose;
Matrix World;
Vector4 Color;
@ -24,14 +25,15 @@ namespace TEN::Renderer::Structures
bool CacheLights;
BoundingSphere OriginalSphere;
BoundingSphere Sphere;
float Scale;
void Update()
void Update(float interpolationFactor)
{
World = (Pose.Orientation.ToRotationMatrix() *
Matrix::CreateScale(Scale) *
Matrix::CreateTranslation(Pose.Position.x, Pose.Position.y, Pose.Position.z));
Sphere = BoundingSphere(Vector3::Transform(OriginalSphere.Center, World), OriginalSphere.Radius * Scale);
auto pos = Vector3::Lerp(PrevPose.Position.ToVector3(), Pose.Position.ToVector3(), interpolationFactor);
auto scale = Vector3::Lerp(PrevPose.Scale, Pose.Scale, interpolationFactor);
auto orient = Matrix::Lerp(PrevPose.Orientation.ToRotationMatrix(), Pose.Orientation.ToRotationMatrix(), interpolationFactor);
World = (orient * Matrix::CreateScale(scale) * Matrix::CreateTranslation(pos));
Sphere = BoundingSphere(Vector3::Transform(OriginalSphere.Center, World), OriginalSphere.Radius * std::max(std::max(Pose.Scale.x, Pose.Scale.y), Pose.Scale.z));
CacheLights = true;
}
};

View file

@ -98,7 +98,8 @@ namespace TEN::Scripting
// @treturn float World scale.
float Static::GetScale() const
{
return _static.scale;
// TODO: Decide what to return when Vector3 scale is also exposed.
return _static.pos.Scale.x;
}
/// Get this static's color.
@ -193,7 +194,7 @@ namespace TEN::Scripting
// @tparam float scale New world scale.
void Static::SetScale(float scale)
{
_static.scale = scale;
_static.pos.Scale = Vector3(scale);
_static.Dirty = true;
}

View file

@ -732,7 +732,7 @@ void LoadDynamicRoomData()
mesh.pos.Orientation.y = ReadUInt16();
mesh.pos.Orientation.x = ReadUInt16();
mesh.pos.Orientation.z = ReadUInt16();
mesh.scale = ReadFloat();
mesh.pos.Scale = Vector3(ReadFloat());
mesh.flags = ReadUInt16();
mesh.color = ReadVector4();
mesh.staticNumber = ReadUInt16();

View file

@ -5205,7 +5205,6 @@ struct StaticMeshInfoT : public flatbuffers::NativeTable {
int32_t number = 0;
int32_t room_number = 0;
std::unique_ptr<TEN::Save::Pose> pose{};
float scale = 0.0f;
std::unique_ptr<TEN::Save::Vector4> color{};
int32_t hit_points = 0;
int32_t flags = 0;
@ -5219,10 +5218,9 @@ struct StaticMeshInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_NUMBER = 4,
VT_ROOM_NUMBER = 6,
VT_POSE = 8,
VT_SCALE = 10,
VT_COLOR = 12,
VT_HIT_POINTS = 14,
VT_FLAGS = 16
VT_COLOR = 10,
VT_HIT_POINTS = 12,
VT_FLAGS = 14
};
int32_t number() const {
return GetField<int32_t>(VT_NUMBER, 0);
@ -5233,9 +5231,6 @@ struct StaticMeshInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const TEN::Save::Pose *pose() const {
return GetStruct<const TEN::Save::Pose *>(VT_POSE);
}
float scale() const {
return GetField<float>(VT_SCALE, 0.0f);
}
const TEN::Save::Vector4 *color() const {
return GetStruct<const TEN::Save::Vector4 *>(VT_COLOR);
}
@ -5250,7 +5245,6 @@ struct StaticMeshInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<int32_t>(verifier, VT_NUMBER) &&
VerifyField<int32_t>(verifier, VT_ROOM_NUMBER) &&
VerifyField<TEN::Save::Pose>(verifier, VT_POSE) &&
VerifyField<float>(verifier, VT_SCALE) &&
VerifyField<TEN::Save::Vector4>(verifier, VT_COLOR) &&
VerifyField<int32_t>(verifier, VT_HIT_POINTS) &&
VerifyField<int32_t>(verifier, VT_FLAGS) &&
@ -5274,9 +5268,6 @@ struct StaticMeshInfoBuilder {
void add_pose(const TEN::Save::Pose *pose) {
fbb_.AddStruct(StaticMeshInfo::VT_POSE, pose);
}
void add_scale(float scale) {
fbb_.AddElement<float>(StaticMeshInfo::VT_SCALE, scale, 0.0f);
}
void add_color(const TEN::Save::Vector4 *color) {
fbb_.AddStruct(StaticMeshInfo::VT_COLOR, color);
}
@ -5302,7 +5293,6 @@ inline flatbuffers::Offset<StaticMeshInfo> CreateStaticMeshInfo(
int32_t number = 0,
int32_t room_number = 0,
const TEN::Save::Pose *pose = 0,
float scale = 0.0f,
const TEN::Save::Vector4 *color = 0,
int32_t hit_points = 0,
int32_t flags = 0) {
@ -5310,7 +5300,6 @@ inline flatbuffers::Offset<StaticMeshInfo> CreateStaticMeshInfo(
builder_.add_flags(flags);
builder_.add_hit_points(hit_points);
builder_.add_color(color);
builder_.add_scale(scale);
builder_.add_pose(pose);
builder_.add_room_number(room_number);
builder_.add_number(number);
@ -10788,7 +10777,6 @@ inline void StaticMeshInfo::UnPackTo(StaticMeshInfoT *_o, const flatbuffers::res
{ auto _e = number(); _o->number = _e; }
{ auto _e = room_number(); _o->room_number = _e; }
{ auto _e = pose(); if (_e) _o->pose = std::unique_ptr<TEN::Save::Pose>(new TEN::Save::Pose(*_e)); }
{ auto _e = scale(); _o->scale = _e; }
{ auto _e = color(); if (_e) _o->color = std::unique_ptr<TEN::Save::Vector4>(new TEN::Save::Vector4(*_e)); }
{ auto _e = hit_points(); _o->hit_points = _e; }
{ auto _e = flags(); _o->flags = _e; }
@ -10805,7 +10793,6 @@ inline flatbuffers::Offset<StaticMeshInfo> CreateStaticMeshInfo(flatbuffers::Fla
auto _number = _o->number;
auto _room_number = _o->room_number;
auto _pose = _o->pose ? _o->pose.get() : 0;
auto _scale = _o->scale;
auto _color = _o->color ? _o->color.get() : 0;
auto _hit_points = _o->hit_points;
auto _flags = _o->flags;
@ -10814,7 +10801,6 @@ inline flatbuffers::Offset<StaticMeshInfo> CreateStaticMeshInfo(flatbuffers::Fla
_number,
_room_number,
_pose,
_scale,
_color,
_hit_points,
_flags);

View file

@ -372,7 +372,6 @@ table StaticMeshInfo {
number: int32;
room_number: int32;
pose: Pose;
scale: float;
color: Vector4;
hit_points: int32;
flags: int32;