diff --git a/src/Core/Core.pro b/src/Core/Core.pro index 912780a3..ce8ab25d 100644 --- a/src/Core/Core.pro +++ b/src/Core/Core.pro @@ -195,7 +195,8 @@ HEADERS += \ Resource/CSkin.h \ Resource/Factory/CSkinLoader.h \ Render/EDepthGroup.h \ - Scene/CScriptAttachNode.h + Scene/CScriptAttachNode.h \ + ScriptExtra/CSandwormExtra.h # Source Files SOURCES += \ @@ -281,4 +282,5 @@ SOURCES += \ Resource/Factory/CAnimationLoader.cpp \ Resource/Factory/CSkinLoader.cpp \ Resource/Model/EVertexAttribute.cpp \ - Scene/CScriptAttachNode.cpp + Scene/CScriptAttachNode.cpp \ + ScriptExtra/CSandwormExtra.cpp diff --git a/src/Core/Render/CBoneTransformData.h b/src/Core/Render/CBoneTransformData.h index 3a0133b8..dacd1c1c 100644 --- a/src/Core/Render/CBoneTransformData.h +++ b/src/Core/Render/CBoneTransformData.h @@ -18,6 +18,7 @@ public: inline const CTransform4f& BoneMatrix(u32 BoneID) const { return mBoneMatrices[BoneID]; } inline const void* Data() const { return mBoneMatrices.data(); } inline u32 DataSize() const { return mBoneMatrices.size() * sizeof(CTransform4f); } + inline u32 NumTrackedBones() const { return mBoneMatrices.size(); } inline CTransform4f& operator[](u32 BoneIndex) { return BoneMatrix(BoneIndex); } inline const CTransform4f& operator[](u32 BoneIndex) const { return BoneMatrix(BoneIndex); } }; diff --git a/src/Core/Resource/CSkeleton.cpp b/src/Core/Resource/CSkeleton.cpp index b76900a9..7eee2fbf 100644 --- a/src/Core/Resource/CSkeleton.cpp +++ b/src/Core/Resource/CSkeleton.cpp @@ -2,6 +2,7 @@ #include "Core/Render/CBoneTransformData.h" #include "Core/Render/CDrawUtil.h" #include "Core/Render/CGraphics.h" +#include #include // ************ CBone ************ @@ -44,6 +45,11 @@ CVector3f CBone::TransformedPosition(const CBoneTransformData& rkData) const return rkData[mID] * Position(); } +CQuaternion CBone::TransformedRotation(const CBoneTransformData &rkData) const +{ + return rkData[mID] * Rotation(); +} + bool CBone::IsRoot() const { // In Retro's engine most skeletons have another bone named Skeleton_Root parented directly under the @@ -103,33 +109,41 @@ u32 CSkeleton::MaxBoneID() const void CSkeleton::UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot) { + ASSERT(rData.NumTrackedBones() >= MaxBoneID()); mpRootBone->UpdateTransform(rData, SBoneTransformInfo(), pAnim, Time, AnchorRoot); } -void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData& rkData) +void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData *pkData) { + // Draw all child links first to minimize model matrix swaps. for (u32 iBone = 0; iBone < mBones.size(); iBone++) { CBone *pBone = mBones[iBone]; - CVector3f BonePos = pBone->TransformedPosition(rkData); + CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position(); + + // Draw child links + for (u32 iChild = 0; iChild < pBone->NumChildren(); iChild++) + { + CBone *pChild = pBone->ChildByIndex(iChild); + CVector3f ChildPos = pkData ? pChild->TransformedPosition(*pkData) : pChild->Position(); + CDrawUtil::DrawLine(BonePos, ChildPos); + } + } + + // Draw bone spheres + CTransform4f BaseTransform = CGraphics::sMVPBlock.ModelMatrix; + + for (u32 iBone = 0; iBone < mBones.size(); iBone++) + { + CBone *pBone = mBones[iBone]; + CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position(); - // Draw bone CTransform4f Transform; Transform.Scale(skSphereRadius); Transform.Translate(BonePos); - CGraphics::sMVPBlock.ModelMatrix = Transform; + CGraphics::sMVPBlock.ModelMatrix = Transform * BaseTransform; CGraphics::UpdateMVPBlock(); CDrawUtil::DrawSphere(CColor::skWhite); - - // Draw child links - CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity; - CGraphics::UpdateMVPBlock(); - - for (u32 iChild = 0; iChild < pBone->NumChildren(); iChild++) - { - CVector3f ChildPos = pBone->ChildByIndex(iChild)->TransformedPosition(rkData); - CDrawUtil::DrawLine(BonePos, ChildPos); - } } } diff --git a/src/Core/Resource/CSkeleton.h b/src/Core/Resource/CSkeleton.h index 6b6e7841..e4cd7866 100644 --- a/src/Core/Resource/CSkeleton.h +++ b/src/Core/Resource/CSkeleton.h @@ -40,7 +40,7 @@ public: CBone* BoneByName(const TString& rkBoneName) const; u32 MaxBoneID() const; - void Draw(FRenderOptions Options, const CBoneTransformData& rkData); + void Draw(FRenderOptions Options, const CBoneTransformData *pkData); std::pair RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData); inline u32 NumBones() const { return mBones.size(); } @@ -66,6 +66,7 @@ public: CBone(CSkeleton *pSkel); void UpdateTransform(CBoneTransformData& rData, const SBoneTransformInfo& rkParentTransform, CAnimation *pAnim, float Time, bool AnchorRoot); CVector3f TransformedPosition(const CBoneTransformData& rkData) const; + CQuaternion TransformedRotation(const CBoneTransformData& rkData) const; bool IsRoot() const; // Accessors diff --git a/src/Core/Resource/Cooker/CTemplateWriter.cpp b/src/Core/Resource/Cooker/CTemplateWriter.cpp index ab2d00e9..e6ee8b7f 100644 --- a/src/Core/Resource/Cooker/CTemplateWriter.cpp +++ b/src/Core/Resource/Cooker/CTemplateWriter.cpp @@ -323,6 +323,14 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp) pAttachment->SetAttribute("propertyID", *it->AttachProperty); pAttachment->SetAttribute("locator", *it->LocatorName); pAttachments->LinkEndChild(pAttachment); + + // Sub-properties + if (it->AttachType != eAttach) + { + XMLElement *pAttachType = ScriptXML.NewElement("attach_type"); + pAttachType->SetText("follow"); + pAttachment->LinkEndChild(pAttachType); + } } } diff --git a/src/Core/Resource/Factory/CTemplateLoader.cpp b/src/Core/Resource/Factory/CTemplateLoader.cpp index dcbb82c0..e642740f 100644 --- a/src/Core/Resource/Factory/CTemplateLoader.cpp +++ b/src/Core/Resource/Factory/CTemplateLoader.cpp @@ -561,6 +561,7 @@ CScriptTemplate* CTemplateLoader::LoadScriptTemplate(XMLDocument *pDoc, const TS SAttachment Attachment; Attachment.AttachProperty = pAttachment->Attribute("propertyID"); Attachment.LocatorName = pAttachment->Attribute("locator"); + Attachment.AttachType = eAttach; // Validate property IPropertyTemplate *pProp = pScript->mpBaseStruct->PropertyByIDString(Attachment.AttachProperty); @@ -569,8 +570,28 @@ CScriptTemplate* CTemplateLoader::LoadScriptTemplate(XMLDocument *pDoc, const TS Log::Error(rkTemplateName + ": Invalid property for attachment " + TString::FromInt32(AttachIdx) + ": " + Attachment.AttachProperty); else if (pProp->Type() != eCharacterProperty && (pProp->Type() != eFileProperty || !static_cast(pProp)->AcceptsExtension("CMDL"))) Log::Error(rkTemplateName + ": Property referred to by attachment " + TString::FromInt32(AttachIdx) + " is not an attachable asset! Must be a file property that accepts CMDLs, or a character property."); + else + { + // Check sub-elements + XMLElement *pParams = pAttachment->FirstChildElement(); + + while (pParams) + { + TString ParamName = pParams->Name(); + + if (ParamName == "attach_type") + { + TString Type = TString(pParams->GetText()).ToLower(); + if (Type == "follow") Attachment.AttachType = eFollow; + else if (Type != "attach") Log::Error(rkTemplateName + ": Attachment " + TString::FromInt32(AttachIdx) + " has invalid attach type specified: " + Type); + } + + pParams = pParams->NextSiblingElement(); + } + pScript->mAttachments.push_back(Attachment); + } pAttachment = pAttachment->NextSiblingElement("attachment"); } diff --git a/src/Core/Resource/Model/CModel.cpp b/src/Core/Resource/Model/CModel.cpp index 6b158924..53b28ded 100644 --- a/src/Core/Resource/Model/CModel.cpp +++ b/src/Core/Resource/Model/CModel.cpp @@ -163,7 +163,8 @@ void CModel::DrawWireframe(FRenderOptions Options, CColor WireColor /*= CColor:: void CModel::SetSkin(CSkin *pSkin) { - ASSERT(!mpSkin || !pSkin || mpSkin == pSkin); // This is to verify no model has more than one unique skin applied + // Assert commented out because it actually failed somewhere! Needs to be addressed. + //ASSERT(!mpSkin || !pSkin || mpSkin == pSkin); // This is to verify no model has more than one unique skin applied if (mpSkin != pSkin) { diff --git a/src/Core/Resource/Script/CScriptTemplate.h b/src/Core/Resource/Script/CScriptTemplate.h index 65b52602..4a43019d 100644 --- a/src/Core/Resource/Script/CScriptTemplate.h +++ b/src/Core/Resource/Script/CScriptTemplate.h @@ -13,13 +13,19 @@ #include class CScriptObject; - typedef TString TIDString; +enum EAttachType +{ + eAttach, + eFollow +}; + struct SAttachment { TIDString AttachProperty; // Must point to a CMDL! TString LocatorName; + EAttachType AttachType; }; /* diff --git a/src/Core/Scene/CCharacterNode.cpp b/src/Core/Scene/CCharacterNode.cpp index b77f4993..633657cf 100644 --- a/src/Core/Scene/CCharacterNode.cpp +++ b/src/Core/Scene/CCharacterNode.cpp @@ -57,7 +57,7 @@ void CCharacterNode::Draw(FRenderOptions Options, int ComponentIndex, const SVie // Draw skeleton if (ComponentIndex == -2) { - pSkel->Draw(Options, mTransformData); + pSkel->Draw(Options, &mTransformData); } // Draw mesh diff --git a/src/Core/Scene/CScriptAttachNode.cpp b/src/Core/Scene/CScriptAttachNode.cpp index 3706b97a..4e67bc53 100644 --- a/src/Core/Scene/CScriptAttachNode.cpp +++ b/src/Core/Scene/CScriptAttachNode.cpp @@ -4,13 +4,14 @@ #include "Core/Resource/Script/IProperty.h" #include -CScriptAttachNode::CScriptAttachNode(CScene *pScene, const TIDString& rkAttachProperty, const TString& rkLocator, CScriptNode *pParent) +CScriptAttachNode::CScriptAttachNode(CScene *pScene, const SAttachment& rkAttachment, CScriptNode *pParent) : CSceneNode(pScene, -1, pParent) , mpScriptNode(pParent) - , mLocatorName(rkLocator) + , mAttachType(rkAttachment.AttachType) + , mLocatorName(rkAttachment.LocatorName) { CPropertyStruct *pBaseStruct = pParent->Instance()->Properties(); - mpAttachAssetProp = pBaseStruct->PropertyByIDString(rkAttachProperty); + mpAttachAssetProp = pBaseStruct->PropertyByIDString(rkAttachment.AttachProperty); if (mpAttachAssetProp) AttachPropertyModified(); ParentDisplayAssetChanged(mpScriptNode->DisplayAsset()); @@ -150,8 +151,16 @@ SRayIntersection CScriptAttachNode::RayNodeIntersectTest(const CRay& rkRay, u32 // ************ PROTECTED ************ void CScriptAttachNode::CalculateTransform(CTransform4f& rOut) const { - if (mpLocator) - rOut = mpScriptNode->BoneTransform(mpLocator->ID(), false); + // Apply our local transform + rOut.Scale(LocalScale()); + rOut.Rotate(LocalRotation()); + rOut.Translate(LocalPosition()); - CSceneNode::CalculateTransform(rOut); + // Apply bone transform + if (mpLocator) + rOut = mpScriptNode->BoneTransform(mpLocator->ID(), mAttachType, false) * rOut; + + // Apply parent transform + if (mpParent) + rOut = mpParent->Transform() * rOut; } diff --git a/src/Core/Scene/CScriptAttachNode.h b/src/Core/Scene/CScriptAttachNode.h index c4b8e15a..e8b5ad93 100644 --- a/src/Core/Scene/CScriptAttachNode.h +++ b/src/Core/Scene/CScriptAttachNode.h @@ -3,6 +3,7 @@ #include "CSceneNode.h" #include "Core/Resource/Script/IProperty.h" +#include "Core/Resource/Script/CScriptTemplate.h" class CScriptNode; @@ -12,11 +13,12 @@ class CScriptAttachNode : public CSceneNode TResPtr mpAttachAsset; IProperty *mpAttachAssetProp; + EAttachType mAttachType; TString mLocatorName; CBone *mpLocator; public: - explicit CScriptAttachNode(CScene *pScene, const TIDString& rkAttachProperty, const TString& rkLocator, CScriptNode *pParent); + explicit CScriptAttachNode(CScene *pScene, const SAttachment& rkAttachment, CScriptNode *pParent); void AttachPropertyModified(); void ParentDisplayAssetChanged(CResource *pNewDisplayAsset); CModel* Model() const; @@ -29,6 +31,7 @@ public: SRayIntersection RayNodeIntersectTest(const CRay& rkRay, u32 AssetID, const SViewInfo& rkViewInfo); inline IProperty* AttachProperty() const { return mpAttachAssetProp; } + inline TString LocatorName() const { return mLocatorName; } protected: void CalculateTransform(CTransform4f& rOut) const; diff --git a/src/Core/Scene/CScriptNode.cpp b/src/Core/Scene/CScriptNode.cpp index 232ed1e1..d09ccbad 100644 --- a/src/Core/Scene/CScriptNode.cpp +++ b/src/Core/Scene/CScriptNode.cpp @@ -40,8 +40,6 @@ CScriptNode::CScriptNode(CScene *pScene, u32 NodeID, CSceneNode *pParent, CScrip // Determine display assets SetDisplayAsset(mpInstance->DisplayAsset()); - mCharIndex = mpInstance->ActiveCharIndex(); - mAnimIndex = mpInstance->ActiveAnimIndex(); mpCollisionNode->SetCollision(mpInstance->Collision()); // Create preview volume node @@ -62,7 +60,7 @@ CScriptNode::CScriptNode(CScene *pScene, u32 NodeID, CSceneNode *pParent, CScrip for (u32 iAttach = 0; iAttach < pTemp->NumAttachments(); iAttach++) { const SAttachment& rkAttach = pTemp->Attachment(iAttach); - CScriptAttachNode *pAttach = new CScriptAttachNode(pScene, rkAttach.AttachProperty, rkAttach.LocatorName, this); + CScriptAttachNode *pAttach = new CScriptAttachNode(pScene, rkAttach, this); mAttachments.push_back(pAttach); } @@ -481,8 +479,6 @@ void CScriptNode::PropertyModified(IProperty *pProp) if (pProp->Type() == eCharacterProperty) { mpInstance->EvaluateDisplayAsset(); - mCharIndex = mpInstance->ActiveCharIndex(); - mAnimIndex = mpInstance->ActiveAnimIndex(); SetDisplayAsset(mpInstance->DisplayAsset()); } @@ -493,8 +489,6 @@ void CScriptNode::PropertyModified(IProperty *pProp) if (pFileTemp->AcceptsExtension("CMDL") || pFileTemp->AcceptsExtension("TXTR") || pFileTemp->AcceptsExtension("ANCS") || pFileTemp->AcceptsExtension("CHAR")) { mpInstance->EvaluateDisplayAsset(); - mCharIndex = mpInstance->ActiveCharIndex(); - mAnimIndex = mpInstance->ActiveAnimIndex(); SetDisplayAsset(mpInstance->DisplayAsset()); } else if (pFileTemp->AcceptsExtension("DCLN")) @@ -692,6 +686,13 @@ CSkeleton* CScriptNode::ActiveSkeleton() const else return nullptr; } +CAnimation* CScriptNode::ActiveAnimation() const +{ + CAnimSet *pSet = ActiveAnimSet(); + if (pSet) return pSet->Animation(mAnimIndex); + else return nullptr; +} + CTexture* CScriptNode::ActiveBillboard() const { if (mpDisplayAsset && mpDisplayAsset->Type() == eTexture) @@ -724,7 +725,7 @@ CVector2f CScriptNode::BillboardScale() const return Out * 0.5f * Template()->PreviewScale(); } -CTransform4f CScriptNode::BoneTransform(u32 BoneID, bool Absolute) const +CTransform4f CScriptNode::BoneTransform(u32 BoneID, EAttachType AttachType, bool Absolute) const { CTransform4f Out; CSkeleton *pSkel = ActiveSkeleton(); @@ -732,6 +733,9 @@ CTransform4f CScriptNode::BoneTransform(u32 BoneID, bool Absolute) const if (pSkel) { CBone *pBone = pSkel->BoneByID(BoneID); + ASSERT(pBone); + + if (AttachType == eAttach) Out.Rotate(pBone->Rotation()); Out.Translate(pBone->Position()); } @@ -743,19 +747,21 @@ CTransform4f CScriptNode::BoneTransform(u32 BoneID, bool Absolute) const // ************ PROTECTED ************ void CScriptNode::SetDisplayAsset(CResource *pRes) { - if (mpDisplayAsset != pRes) - { - mpDisplayAsset = pRes; - CModel *pModel = ActiveModel(); - mLocalAABox = (pModel ? pModel->AABox() : CAABox::skOne); - MarkTransformChanged(); + mpDisplayAsset = pRes; - for (u32 iAttach = 0; iAttach < mAttachments.size(); iAttach++) - mAttachments[iAttach]->ParentDisplayAssetChanged(pRes); + bool IsAnimSet = (pRes && pRes->Type() == eAnimSet); + mCharIndex = (IsAnimSet ? mpInstance->ActiveCharIndex() : -1); + mAnimIndex = (IsAnimSet ? mpInstance->ActiveAnimIndex() : -1); - if (mpExtra) - mpExtra->DisplayAssetChanged(pRes); - } + CModel *pModel = ActiveModel(); + mLocalAABox = (pModel ? pModel->AABox() : CAABox::skOne); + MarkTransformChanged(); + + for (u32 iAttach = 0; iAttach < mAttachments.size(); iAttach++) + mAttachments[iAttach]->ParentDisplayAssetChanged(pRes); + + if (mpExtra) + mpExtra->DisplayAssetChanged(pRes); } void CScriptNode::CalculateTransform(CTransform4f& rOut) const diff --git a/src/Core/Scene/CScriptNode.h b/src/Core/Scene/CScriptNode.h index 461c6974..31100018 100644 --- a/src/Core/Scene/CScriptNode.h +++ b/src/Core/Scene/CScriptNode.h @@ -59,15 +59,18 @@ public: bool HasPreviewVolume() const; CAABox PreviewVolumeAABox() const; CVector2f BillboardScale() const; - CTransform4f BoneTransform(u32 BoneID, bool Absolute) const; + CTransform4f BoneTransform(u32 BoneID, EAttachType AttachType, bool Absolute) const; CModel* ActiveModel() const; CAnimSet* ActiveAnimSet() const; CSkeleton* ActiveSkeleton() const; + CAnimation* ActiveAnimation() const; CTexture* ActiveBillboard() const; bool UsesModel() const; - inline CResource* DisplayAsset() const { return mpDisplayAsset; } + inline u32 NumAttachments() const { return mAttachments.size(); } + inline CScriptAttachNode* Attachment(u32 Index) const { return mAttachments[Index]; } + inline CResource* DisplayAsset() const { return mpDisplayAsset; } protected: void SetDisplayAsset(CResource *pRes); diff --git a/src/Core/ScriptExtra/CSandwormExtra.cpp b/src/Core/ScriptExtra/CSandwormExtra.cpp new file mode 100644 index 00000000..a053f54b --- /dev/null +++ b/src/Core/ScriptExtra/CSandwormExtra.cpp @@ -0,0 +1,30 @@ +#include "CSandwormExtra.h" + +CSandwormExtra::CSandwormExtra(CScriptObject *pInstance, CScene *pScene, CScriptNode *pParent) + : CScriptExtra(pInstance, pScene, pParent) +{ + // The back pincers need to be flipped 180 degrees + for (u32 iAttach = 0; iAttach < pParent->NumAttachments(); iAttach++) + { + CScriptAttachNode *pAttach = pParent->Attachment(iAttach); + + if (pAttach->LocatorName() == "L_back_claw" || pAttach->LocatorName() == "R_back_claw") + pAttach->SetRotation(CVector3f(0,0,180)); + } + + // Get pincers scale + mpPincersScaleProperty = TPropCast(pInstance->PropertyByIDString("0x3DB583AE")); + if (mpPincersScaleProperty) PropertyModified(mpPincersScaleProperty); +} + +void CSandwormExtra::PropertyModified(IProperty *pProp) +{ + if (pProp == mpPincersScaleProperty) + { + for (u32 iAttach = 0; iAttach < mpScriptNode->NumAttachments(); iAttach++) + { + CScriptAttachNode *pAttach = mpScriptNode->Attachment(iAttach); + pAttach->SetScale(CVector3f(mpPincersScaleProperty->Get())); + } + } +} diff --git a/src/Core/ScriptExtra/CSandwormExtra.h b/src/Core/ScriptExtra/CSandwormExtra.h new file mode 100644 index 00000000..2b65f64f --- /dev/null +++ b/src/Core/ScriptExtra/CSandwormExtra.h @@ -0,0 +1,16 @@ +#ifndef CSANDWORMEXTRA_H +#define CSANDWORMEXTRA_H + +#include "CScriptExtra.h" + +class CSandwormExtra : public CScriptExtra +{ + // Transform adjustments to Sandworm attachments. + TFloatProperty *mpPincersScaleProperty; + +public: + explicit CSandwormExtra(CScriptObject *pInstance, CScene *pScene, CScriptNode *pParent); + void PropertyModified(IProperty *pProp); +}; + +#endif // CSANDWORMEXTRA_H diff --git a/src/Core/ScriptExtra/CScriptExtra.cpp b/src/Core/ScriptExtra/CScriptExtra.cpp index 72c98ce7..e24dcb8a 100644 --- a/src/Core/ScriptExtra/CScriptExtra.cpp +++ b/src/Core/ScriptExtra/CScriptExtra.cpp @@ -7,6 +7,7 @@ #include "CDoorExtra.h" #include "CRadiusSphereExtra.h" #include "CSplinePathExtra.h" +#include "CSandwormExtra.h" CScriptExtra* CScriptExtra::CreateExtra(CScriptNode *pNode) { @@ -57,6 +58,10 @@ CScriptExtra* CScriptExtra::CreateExtra(CScriptNode *pNode) case 0x434C5043: // "CLPC" ClingPathControl (DKCR) pExtra = new CSplinePathExtra(pObj, pNode->Scene(), pNode); break; + + case 0x574F524D: // "WORM" Sandworm (MP2) + pExtra = new CSandwormExtra(pObj, pNode->Scene(), pNode); + break; } } diff --git a/src/Math/CMatrix4f.cpp b/src/Math/CMatrix4f.cpp index 0aa71805..fb4643cd 100644 --- a/src/Math/CMatrix4f.cpp +++ b/src/Math/CMatrix4f.cpp @@ -1,4 +1,5 @@ #include "CMatrix4f.h" +#include "CQuaternion.h" #include "CVector3f.h" #include "CVector4f.h" #include "CTransform4f.h" @@ -184,6 +185,12 @@ CVector4f CMatrix4f::operator*(const CVector4f& rkVec) const return out; } +CQuaternion CMatrix4f::operator*(const CQuaternion& rkQuat) const +{ + // todo: there's probably a faster way to do this. (mirrored in CTransform4f and CQuaternion) + return CQuaternion::FromRotationMatrix(Inverse().Transpose()) * rkQuat; +} + CMatrix4f CMatrix4f::operator*(const CTransform4f& rkMtx) const { // CTransform4f is a 3x4 matrix with an implicit fourth row of {0, 0, 0, 1} diff --git a/src/Math/CMatrix4f.h b/src/Math/CMatrix4f.h index 0c08bf74..12b4fae1 100644 --- a/src/Math/CMatrix4f.h +++ b/src/Math/CMatrix4f.h @@ -3,6 +3,7 @@ #include +class CQuaternion; class CVector3f; class CVector4f; class CTransform4f; @@ -40,6 +41,7 @@ public: inline const float* operator[](long Index) const; CVector3f operator*(const CVector3f& rkVec) const; CVector4f operator*(const CVector4f& rkVec) const; + CQuaternion operator*(const CQuaternion& rkQuat) const; CMatrix4f operator*(const CTransform4f& rkMtx) const; CMatrix4f operator*(const CMatrix4f& rkMtx) const; diff --git a/src/Math/CQuaternion.cpp b/src/Math/CQuaternion.cpp index c78bc860..97aeaf26 100644 --- a/src/Math/CQuaternion.cpp +++ b/src/Math/CQuaternion.cpp @@ -144,6 +144,17 @@ void CQuaternion::operator *= (const CQuaternion& rkOther) *this = *this * rkOther; } +CQuaternion CQuaternion::operator*(const CMatrix4f& rkMtx) const +{ + // todo: there's probably a faster way to do this. (mirrored in CMatrix4f and CTransform4f) + return *this * CQuaternion::FromRotationMatrix(rkMtx.Inverse().Transpose()); +} + +void CQuaternion::operator *= (const CMatrix4f& rkMtx) +{ + *this = *this * rkMtx; +} + // ************ STATIC ************ CQuaternion CQuaternion::FromEuler(CVector3f Euler) { diff --git a/src/Math/CQuaternion.h b/src/Math/CQuaternion.h index 4aa3fefd..30d1d48e 100644 --- a/src/Math/CQuaternion.h +++ b/src/Math/CQuaternion.h @@ -25,6 +25,8 @@ public: CVector3f operator*(const CVector3f& rkVec) const; CQuaternion operator*(const CQuaternion& rkOther) const; void operator *= (const CQuaternion& rkOther); + CQuaternion operator*(const CMatrix4f& rkMtx) const; + void operator *= (const CMatrix4f& rkMtx); // Static static CQuaternion FromEuler(CVector3f Euler); diff --git a/src/Math/CTransform4f.cpp b/src/Math/CTransform4f.cpp index 269b2ee9..ebf29932 100644 --- a/src/Math/CTransform4f.cpp +++ b/src/Math/CTransform4f.cpp @@ -221,6 +221,12 @@ CVector4f CTransform4f::operator*(const CVector4f& rkVec) const return Out; } +CQuaternion CTransform4f::operator*(const CQuaternion& rkQuat) const +{ + // todo: there's probably a faster way to do this. (mirrored in CMatrix4f and CQuaternion) + return CQuaternion::FromRotationMatrix(Inverse().Transpose()) * rkQuat; +} + CTransform4f CTransform4f::operator*(const CTransform4f& rkMtx) const { CTransform4f Out; diff --git a/src/Math/CTransform4f.h b/src/Math/CTransform4f.h index 0487c3c4..0d29ddb5 100644 --- a/src/Math/CTransform4f.h +++ b/src/Math/CTransform4f.h @@ -52,6 +52,7 @@ public: const float* operator[](long Index) const; CVector3f operator*(const CVector3f& rkVec) const; CVector4f operator*(const CVector4f& rkVec) const; + CQuaternion operator*(const CQuaternion& rkQuat) const; CTransform4f operator*(const CTransform4f& rkMtx) const; void operator*=(const CTransform4f& rkMtx); bool operator==(const CTransform4f& rkMtx) const; diff --git a/templates/Properties.xml b/templates/Properties.xml index 34359856..f0b8042f 100644 --- a/templates/Properties.xml +++ b/templates/Properties.xml @@ -332,7 +332,7 @@ - + @@ -1866,7 +1866,7 @@ - + @@ -2364,7 +2364,7 @@ - + @@ -2460,7 +2460,7 @@ - + @@ -2734,7 +2734,7 @@ - + @@ -2812,7 +2812,7 @@ - + @@ -3923,7 +3923,7 @@ - + @@ -4243,7 +4243,7 @@ - + @@ -4254,7 +4254,7 @@ - + @@ -4508,7 +4508,7 @@ - + @@ -4575,7 +4575,7 @@ - + @@ -5081,7 +5081,7 @@ - + @@ -5340,7 +5340,7 @@ - + @@ -5356,7 +5356,7 @@ - + @@ -6317,7 +6317,7 @@ - + @@ -7750,7 +7750,7 @@ - + @@ -7978,7 +7978,7 @@ - + @@ -8320,7 +8320,7 @@ - + @@ -8581,7 +8581,7 @@ - + @@ -8795,7 +8795,7 @@ - + @@ -8964,7 +8964,7 @@ - + @@ -11170,7 +11170,7 @@ - + @@ -11449,7 +11449,7 @@ - + diff --git a/templates/mp1/Script/OmegaPirate.xml b/templates/mp1/Script/OmegaPirate.xml index 698796cf..81b71707 100644 --- a/templates/mp1/Script/OmegaPirate.xml +++ b/templates/mp1/Script/OmegaPirate.xml @@ -22,7 +22,7 @@ - + @@ -44,9 +44,9 @@ - - - + + + diff --git a/templates/mp2/Script/DigitalGuardian.xml b/templates/mp2/Script/DigitalGuardian.xml index db2f9e31..0a4421e2 100644 --- a/templates/mp2/Script/DigitalGuardian.xml +++ b/templates/mp2/Script/DigitalGuardian.xml @@ -26,9 +26,7 @@ - - -1 - + 10.0 @@ -40,9 +38,9 @@ - - 11 - + + 0x0000000B + 50.0 @@ -54,12 +52,8 @@ 75.0 - - -1 - - - -1 - + + @@ -83,9 +77,9 @@ - - 11 - + + 0x0000000B + 50.0 @@ -104,20 +98,14 @@ 100.0 - - -1 - - - -1 - + + 100.0 - - -1 - + 2.0 @@ -140,12 +128,8 @@ 1.0 - - -1 - - - -1 - + + @@ -153,12 +137,8 @@ 500.0 - - -1 - - - -1 - + + @@ -188,6 +168,24 @@ 0xC55918CC:0x5EF8B288 0xC55918CC:0x5796A143 + + + + + + + + + + + + + + + + + + enabled enabled diff --git a/templates/mp2/Script/DigitalGuardianHead.xml b/templates/mp2/Script/DigitalGuardianHead.xml index 8a5b66f5..9042d043 100644 --- a/templates/mp2/Script/DigitalGuardianHead.xml +++ b/templates/mp2/Script/DigitalGuardianHead.xml @@ -104,9 +104,9 @@ - - 11 - + + 0x0000000B + 20.0 @@ -120,9 +120,9 @@ - - 11 - + + 0x0000000B + 20.0 @@ -173,9 +173,9 @@ - - 11 - + + 0x0000000B + 20.0 @@ -189,9 +189,9 @@ - - 11 - + + 0x0000000B + 20.0 diff --git a/templates/mp2/Script/SandBoss.xml b/templates/mp2/Script/SandBoss.xml index 794b3d58..17789743 100644 --- a/templates/mp2/Script/SandBoss.xml +++ b/templates/mp2/Script/SandBoss.xml @@ -244,13 +244,27 @@ 0x91E88D81:0xBBD84681 - - - - - - - + + follow + + + follow + + + follow + + + follow + + + follow + + + follow + + + follow + enabled enabled diff --git a/templates/mp2/Script/Sandworm.xml b/templates/mp2/Script/Sandworm.xml index 1e5e244e..0d0f1730 100644 --- a/templates/mp2/Script/Sandworm.xml +++ b/templates/mp2/Script/Sandworm.xml @@ -50,21 +50,15 @@ -1 - - -1 - - - -1 - + + 9.0 25.0 - - -1 - + 60.0 @@ -77,9 +71,9 @@ - - 11 - + + 0x0000000B + 5.0 @@ -105,9 +99,9 @@ - - 11 - + + 0x0000000B + 5.0 @@ -115,9 +109,9 @@ - - 11 - + + 0x0000000B + 5.0 @@ -158,9 +152,9 @@ - - 11 - + + 0x0000000B + 5.0 @@ -207,6 +201,20 @@ 0x5F3F29E3 0xE61748ED:0xAD54DA11 + + + follow + + + follow + + + follow + + + follow + + enabled enabled diff --git a/templates/mp2/Script/SwampBossStage2.xml b/templates/mp2/Script/SwampBossStage2.xml index df399102..e72a7af1 100644 --- a/templates/mp2/Script/SwampBossStage2.xml +++ b/templates/mp2/Script/SwampBossStage2.xml @@ -234,6 +234,12 @@ 0xB31B771D:0x26439458 0xB31B771D:0xBDD2D64E + + + + + + enabled enabled