Fixes using gameobject like chairs, also fixes indoor checks

This commit is contained in:
hondacrx
2022-07-13 15:02:06 -04:00
parent 206c5afcca
commit d05595e44c
9 changed files with 168 additions and 48 deletions
+15 -15
View File
@@ -65,13 +65,13 @@ namespace Game.Collision
iScale = modelOwner.GetScale();
iInvScale = 1.0f / iScale;
Matrix4x4 iRotation = Matrix4x4.CreateFromQuaternion(modelOwner.GetRotation());
Matrix4x4.Invert(iRotation, out iInvRot);
Matrix4x4 iRotation = modelOwner.GetRotation().ToMatrix();
iRotation.Inverse(out iInvRot);
// transform bounding box:
mdl_box = new AxisAlignedBox(mdl_box.Lo * iScale, mdl_box.Hi * iScale);
AxisAlignedBox rotated_bounds = new();
for (int i = 0; i < 8; ++i)
rotated_bounds.merge(Vector3.TransformNormal(mdl_box.corner(i), iRotation));
rotated_bounds.merge(iRotation.Multiply(mdl_box.corner(i)));
iBound = rotated_bounds + iPos;
owner = modelOwner;
@@ -101,8 +101,8 @@ namespace Game.Collision
return false;
// child bounds are defined in object space:
Vector3 p = Vector3.TransformNormal((ray.Origin - iPos) * iInvScale, iInvRot);
Ray modRay = new Ray(p, Vector3.TransformNormal(ray.Direction, iInvRot));
Vector3 p = iInvRot.Multiply(ray.Origin - iPos) * iInvScale;
Ray modRay = new Ray(p, iInvRot.Multiply(ray.Direction));
float distance = maxDist * iInvScale;
bool hit = iModel.IntersectRay(modRay, ref distance, stopAtFirstHit, ignoreFlags);
if (hit)
@@ -125,13 +125,13 @@ namespace Game.Collision
return;
// child bounds are defined in object space:
Vector3 pModel = Vector3.TransformNormal((point - iPos) * iInvScale, iInvRot);
Vector3 zDirModel = Vector3.TransformNormal(new Vector3(0.0f, 0.0f, -1.0f), iInvRot);
Vector3 pModel = iInvRot.Multiply(point - iPos) * iInvScale;
Vector3 zDirModel = iInvRot.Multiply(new Vector3(0.0f, 0.0f, -1.0f));
float zDist;
if (iModel.IntersectPoint(pModel, zDirModel, out zDist, info))
{
Vector3 modelGround = pModel + zDist * zDirModel;
float world_Z = (Vector3.TransformNormal(modelGround, iInvRot) * iScale + iPos).Z;
float world_Z = (iInvRot.Multiply(modelGround) * iScale + iPos).Z;
if (info.ground_Z < world_Z)
{
info.ground_Z = world_Z;
@@ -152,13 +152,13 @@ namespace Game.Collision
return false;
// child bounds are defined in object space:
Vector3 pModel = Vector3.TransformNormal((point - iPos) * iInvScale, iInvRot);
Vector3 zDirModel = Vector3.TransformNormal(new Vector3(0.0f, 0.0f, -1.0f), iInvRot);
Vector3 pModel = iInvRot.Multiply(point - iPos) * iInvScale;
Vector3 zDirModel = iInvRot.Multiply(new Vector3(0.0f, 0.0f, -1.0f));
float zDist;
if (iModel.GetLocationInfo(pModel, zDirModel, out zDist, info))
{
Vector3 modelGround = pModel + zDist * zDirModel;
float world_Z = (Vector3.TransformNormal(modelGround, iInvRot) * iScale + iPos).Z;
float world_Z = (iInvRot.Multiply(modelGround) * iScale + iPos).Z;
if (info.ground_Z < world_Z)
{
info.ground_Z = world_Z;
@@ -172,7 +172,7 @@ namespace Game.Collision
public bool GetLiquidLevel(Vector3 point, LocationInfo info, ref float liqHeight)
{
// child bounds are defined in object space:
Vector3 pModel = Vector3.TransformNormal((point - iPos) * iInvScale, iInvRot);
Vector3 pModel = iInvRot.Multiply(point - iPos) * iInvScale;
//Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
float zDist;
if (info.hitModel.GetLiquidLevel(pModel, out zDist))
@@ -204,13 +204,13 @@ namespace Game.Collision
iPos = owner.GetPosition();
Matrix4x4 iRotation = Matrix4x4.CreateFromQuaternion(owner.GetRotation());
Matrix4x4.Invert(iRotation, out iInvRot);
Matrix4x4 iRotation = owner.GetRotation().ToMatrix();
iRotation.Inverse(out iInvRot);
// transform bounding box:
mdl_box = new AxisAlignedBox(mdl_box.Lo * iScale, mdl_box.Hi * iScale);
AxisAlignedBox rotated_bounds = new();
for (int i = 0; i < 8; ++i)
rotated_bounds.merge(Vector3.TransformNormal(mdl_box.corner(i), iRotation));
rotated_bounds.merge(iRotation.Multiply(mdl_box.corner(i)));
iBound = rotated_bounds + iPos;
+10 -10
View File
@@ -108,7 +108,7 @@ namespace Game.Collision
iModel = model;
Matrix4x4.Invert(Extensions.fromEulerAnglesZYX(MathFunctions.PI * spawn.iRot.Y / 180.0f, MathFunctions.PI * spawn.iRot.X / 180.0f, MathFunctions.PI * spawn.iRot.Z / 180.0f), out iInvRot);
Extensions.fromEulerAnglesZYX(MathFunctions.PI * spawn.iRot.Y / 180.0f, MathFunctions.PI * spawn.iRot.X / 180.0f, MathFunctions.PI * spawn.iRot.Z / 180.0f).Inverse(out iInvRot);
iInvScale = 1.0f / iScale;
}
@@ -123,8 +123,8 @@ namespace Game.Collision
return false;
// child bounds are defined in object space:
Vector3 p = Vector3.TransformNormal((pRay.Origin - iPos) * iInvScale, iInvRot);
Ray modRay = new Ray(p, Vector3.TransformNormal(pRay.Direction, iInvRot));
Vector3 p = iInvRot.Multiply(pRay.Origin - iPos) * iInvScale;
Ray modRay = new Ray(p, iInvRot.Multiply(pRay.Direction));
float distance = pMaxDist * iInvScale;
bool hit = iModel.IntersectRay(modRay, ref distance, pStopAtFirstHit, ignoreFlags);
if (hit)
@@ -146,8 +146,8 @@ namespace Game.Collision
if (!iBound.contains(p))
return;
// child bounds are defined in object space:
Vector3 pModel = Vector3.TransformNormal((p - iPos) * iInvScale, iInvRot);
Vector3 zDirModel = Vector3.TransformNormal(new Vector3(0.0f, 0.0f, -1.0f), iInvRot);
Vector3 pModel = iInvRot.Multiply(p - iPos) * iInvScale;
Vector3 zDirModel = iInvRot.Multiply(new Vector3(0.0f, 0.0f, -1.0f));
float zDist;
if (iModel.IntersectPoint(pModel, zDirModel, out zDist, info))
{
@@ -155,7 +155,7 @@ namespace Game.Collision
// Transform back to world space. Note that:
// Mat * vec == vec * Mat.transpose()
// and for rotation matrices: Mat.inverse() == Mat.transpose()
float world_Z = ((Vector3.TransformNormal(modelGround, iInvRot)) * iScale + iPos).Z;
float world_Z = (iInvRot.Multiply(modelGround) * iScale + iPos).Z;
if (info.ground_Z < world_Z)
{
info.ground_Z = world_Z;
@@ -167,7 +167,7 @@ namespace Game.Collision
public bool GetLiquidLevel(Vector3 p, LocationInfo info, ref float liqHeight)
{
// child bounds are defined in object space:
Vector3 pModel = Vector3.TransformNormal((p - iPos) * iInvScale, iInvRot);
Vector3 pModel = iInvRot.Multiply(p - iPos) * iInvScale;
//Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
float zDist;
if (info.hitModel.GetLiquidLevel(pModel, out zDist))
@@ -191,8 +191,8 @@ namespace Game.Collision
if (!iBound.contains(p))
return false;
// child bounds are defined in object space:
Vector3 pModel = Vector3.TransformNormal((p - iPos) * iInvScale, iInvRot);
Vector3 zDirModel = Vector3.TransformNormal(new Vector3(0.0f, 0.0f, -1.0f), iInvRot);
Vector3 pModel = iInvRot.Multiply(p - iPos) * iInvScale;
Vector3 zDirModel = iInvRot.Multiply(new Vector3(0.0f, 0.0f, -1.0f));
float zDist;
if (iModel.GetLocationInfo(pModel, zDirModel, out zDist, info))
{
@@ -200,7 +200,7 @@ namespace Game.Collision
// Transform back to world space. Note that:
// Mat * vec == vec * Mat.transpose()
// and for rotation matrices: Mat.inverse() == Mat.transpose()
float world_Z = (Vector3.TransformNormal(modelGround, iInvRot) * iScale + iPos).Z;
float world_Z = (iInvRot.Multiply(modelGround * iScale) + iPos).Z;
if (info.ground_Z < world_Z) // hm...could it be handled automatically with zDist at intersection?
{
info.ground_Z = world_Z;
@@ -2446,10 +2446,10 @@ namespace Game.Entities
float maxY = displayInfo.GeoBoxMax.Y * scale + radius;
float maxZ = displayInfo.GeoBoxMax.Z * scale + radius;
Quaternion worldRotation = GetLocalRotation();
Quaternion worldRotation = GetWorldRotation();
//Todo Test this. Needs checked.
var worldSpaceBox = MathFunctions.toWorldSpace(Matrix4x4.CreateFromQuaternion(worldRotation), new Vector3(GetPositionX(), GetPositionY(), GetPositionZ()), new Box(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ)));
var worldSpaceBox = MathFunctions.toWorldSpace(worldRotation.ToMatrix(), new Vector3(GetPositionX(), GetPositionY(), GetPositionZ()), new Box(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ)));
return worldSpaceBox.Contains(new Vector3(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()));
}
@@ -3743,15 +3743,15 @@ namespace Game.Entities
TransportAnimationRecord newAnimation = _animationInfo.GetNextAnimNode(newProgress);
if (oldAnimation != null && newAnimation != null)
{
Matrix4x4 pathRotation = Matrix4x4.CreateFromQuaternion(new Quaternion(_owner.m_gameObjectData.ParentRotation.GetValue().X, _owner.m_gameObjectData.ParentRotation.GetValue().Y,
_owner.m_gameObjectData.ParentRotation.GetValue().Z, _owner.m_gameObjectData.ParentRotation.GetValue().W));
Matrix4x4 pathRotation = new Quaternion(_owner.m_gameObjectData.ParentRotation.GetValue().X, _owner.m_gameObjectData.ParentRotation.GetValue().Y,
_owner.m_gameObjectData.ParentRotation.GetValue().Z, _owner.m_gameObjectData.ParentRotation.GetValue().W).ToMatrix();
Vector3 prev = new(oldAnimation.Pos.X, oldAnimation.Pos.Y, oldAnimation.Pos.Z);
Vector3 next = new(newAnimation.Pos.X, newAnimation.Pos.Y, newAnimation.Pos.Z);
float animProgress = (float)(newProgress - oldAnimation.TimeIndex) / (float)(newAnimation.TimeIndex - oldAnimation.TimeIndex);
Vector3 dst = Vector3.TransformNormal(Vector3.Lerp(prev, next, animProgress), pathRotation);//todo check this
Vector3 dst = pathRotation.Multiply(Vector3.Lerp(prev, next, animProgress));
dst += _owner.GetStationaryPosition();