mirror of https://github.com/AxioDL/metaforce.git
Add CPU-based skinning path for vertex manipulation effects
This commit is contained in:
parent
d67d6a1aa7
commit
c66f9d0ec7
|
@ -1473,7 +1473,8 @@ template bool WriteCMDL<DNAMP1::MaterialSet, DNACMDL::SurfaceHeader_1, 2>
|
||||||
(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
|
(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
|
||||||
|
|
||||||
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
|
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
|
||||||
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh)
|
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
|
||||||
|
const Mesh& mesh, hecl::PoolSkinIndex& poolSkinIndex)
|
||||||
{
|
{
|
||||||
Header head;
|
Header head;
|
||||||
head.magic = 0xDEADBABE;
|
head.magic = 0xDEADBABE;
|
||||||
|
@ -1536,7 +1537,7 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hecl::HMDLBuffers bufs = mesh.getHMDLBuffers(false);
|
hecl::HMDLBuffers bufs = mesh.getHMDLBuffers(false, poolSkinIndex);
|
||||||
|
|
||||||
/* Metadata */
|
/* Metadata */
|
||||||
size_t secSz = bufs.m_meta.binarySize(0);
|
size_t secSz = bufs.m_meta.binarySize(0);
|
||||||
|
@ -1643,7 +1644,8 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
|
||||||
}
|
}
|
||||||
|
|
||||||
template bool WriteHMDLCMDL<DNAMP1::HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>
|
template bool WriteHMDLCMDL<DNAMP1::HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>
|
||||||
(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
|
(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh,
|
||||||
|
hecl::PoolSkinIndex& poolSkinIndex);
|
||||||
|
|
||||||
template <class MaterialSet, class SurfaceHeader, class MeshHeader>
|
template <class MaterialSet, class SurfaceHeader, class MeshHeader>
|
||||||
bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath,
|
bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath,
|
||||||
|
@ -1757,7 +1759,8 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
|
||||||
meshHeader.write(w);
|
meshHeader.write(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
hecl::HMDLBuffers bufs = mesh.getHMDLBuffers(true);
|
hecl::PoolSkinIndex poolSkinIndex;
|
||||||
|
hecl::HMDLBuffers bufs = mesh.getHMDLBuffers(true, poolSkinIndex);
|
||||||
|
|
||||||
std::vector<size_t> surfEndOffs;
|
std::vector<size_t> surfEndOffs;
|
||||||
surfEndOffs.reserve(bufs.m_surfaces.size());
|
surfEndOffs.reserve(bufs.m_surfaces.size());
|
||||||
|
|
|
@ -169,7 +169,8 @@ template <class MaterialSet, class SurfaceHeader, atUint32 Version>
|
||||||
bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
|
bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
|
||||||
|
|
||||||
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
|
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
|
||||||
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
|
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
|
||||||
|
const Mesh& mesh, hecl::PoolSkinIndex& poolSkinIndex);
|
||||||
|
|
||||||
template <class MaterialSet, class SurfaceHeader, class MeshHeader>
|
template <class MaterialSet, class SurfaceHeader, class MeshHeader>
|
||||||
bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath,
|
bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath,
|
||||||
|
|
|
@ -34,12 +34,12 @@ struct SChargedShotParam : SShotParam
|
||||||
struct ITweakPlayerGun : ITweak
|
struct ITweakPlayerGun : ITweak
|
||||||
{
|
{
|
||||||
DECL_YAML
|
DECL_YAML
|
||||||
virtual float GetX24() const = 0; // x24
|
virtual float GetAimVerticalSpeed() const = 0; // x24
|
||||||
virtual float GetX28() const = 0; // x28
|
virtual float GetAimHorizontalSpeed() const = 0; // x28
|
||||||
virtual float GetX2c() const = 0; // x2c
|
virtual float GetBombFuseTime() const = 0; // x2c
|
||||||
virtual float GetX30() const = 0; // x30
|
virtual float GetBombDropDelayTime() const = 0; // x30
|
||||||
virtual float GetX34() const = 0; // x34
|
virtual float GetHoloHoldTime() const = 0; // x34
|
||||||
virtual float GetX38() const = 0; // x38
|
virtual float GetGunTransformTime() const = 0; // x38
|
||||||
virtual float GetGunHolsterTime() const=0;
|
virtual float GetGunHolsterTime() const=0;
|
||||||
virtual float GetGunNotFiringTime() const=0;
|
virtual float GetGunNotFiringTime() const=0;
|
||||||
virtual float GetFixedVerticalAim() const=0;
|
virtual float GetFixedVerticalAim() const=0;
|
||||||
|
|
|
@ -1263,6 +1263,30 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath,
|
||||||
for (uint32_t i=0 ; i<boneNameCount ; ++i)
|
for (uint32_t i=0 ; i<boneNameCount ; ++i)
|
||||||
boneNames.push_back(skinIO.readString());
|
boneNames.push_back(skinIO.readString());
|
||||||
|
|
||||||
|
std::vector<std::vector<std::pair<uint32_t, float>>> skins;
|
||||||
|
uint32_t skinCount = skinIO.readUint32Big();
|
||||||
|
skins.resize(skinCount);
|
||||||
|
for (uint32_t i=0 ; i<skinCount ; ++i)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<uint32_t, float>>& virtualBone = skins[i];
|
||||||
|
uint32_t bindCount = skinIO.readUint32Big();
|
||||||
|
virtualBone.reserve(bindCount);
|
||||||
|
for (uint32_t j=0 ; j<bindCount ; ++j)
|
||||||
|
{
|
||||||
|
uint32_t bIdx = skinIO.readUint32Big();
|
||||||
|
float weight = skinIO.readFloatBig();
|
||||||
|
const std::string& name = boneNames[bIdx];
|
||||||
|
auto search = boneIdMap.find(name);
|
||||||
|
if (search == boneIdMap.cend())
|
||||||
|
Log.report(logvisor::Fatal, "unable to find bone '%s' in %s",
|
||||||
|
name.c_str(), inPath.getRelativePathUTF8().c_str());
|
||||||
|
virtualBone.emplace_back(search->second, weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
atUint64 uniquePoolIndexLen = skinIO.length() - skinIO.position();
|
||||||
|
auto uniquePoolIndexData = skinIO.readUBytes(uniquePoolIndexLen);
|
||||||
|
|
||||||
skinIO.close();
|
skinIO.close();
|
||||||
|
|
||||||
athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath());
|
athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath());
|
||||||
|
@ -1282,6 +1306,19 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skinOut.writeUint32Big(skins.size());
|
||||||
|
for (auto& virtuaBone : skins)
|
||||||
|
{
|
||||||
|
skinOut.writeUint32Big(virtuaBone.size());
|
||||||
|
for (auto& bind : virtuaBone)
|
||||||
|
{
|
||||||
|
skinOut.writeUint32Big(bind.first);
|
||||||
|
skinOut.writeFloatBig(bind.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
skinOut.writeUBytes(uniquePoolIndexData.get(), uniquePoolIndexLen);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,9 +120,11 @@ struct CMDL
|
||||||
const hecl::ProjectPath& inPath,
|
const hecl::ProjectPath& inPath,
|
||||||
const DNACMDL::Mesh& mesh)
|
const DNACMDL::Mesh& mesh)
|
||||||
{
|
{
|
||||||
|
hecl::PoolSkinIndex poolSkinIndex;
|
||||||
if (mesh.skins.size())
|
if (mesh.skins.size())
|
||||||
{
|
{
|
||||||
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(outPath, inPath, mesh))
|
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(
|
||||||
|
outPath, inPath, mesh, poolSkinIndex))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Output skinning intermediate */
|
/* Output skinning intermediate */
|
||||||
|
@ -137,8 +139,26 @@ struct CMDL
|
||||||
writer.writeUint32Big(mesh.boneNames.size());
|
writer.writeUint32Big(mesh.boneNames.size());
|
||||||
for (const std::string& boneName : mesh.boneNames)
|
for (const std::string& boneName : mesh.boneNames)
|
||||||
writer.writeString(boneName);
|
writer.writeString(boneName);
|
||||||
|
|
||||||
|
/* CVirtualBone structure just like original (for CPU skinning) */
|
||||||
|
writer.writeUint32Big(mesh.skins.size());
|
||||||
|
for (auto& s : mesh.skins)
|
||||||
|
{
|
||||||
|
writer.writeUint32Big(s.size());
|
||||||
|
for (auto& b : s)
|
||||||
|
{
|
||||||
|
writer.writeUint32Big(b.boneIdx);
|
||||||
|
writer.writeFloatBig(b.weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write indirection table mapping pool verts to CVirtualBones */
|
||||||
|
writer.writeUint32Big(poolSkinIndex.m_poolSz);
|
||||||
|
for (uint32_t i=0 ; i<poolSkinIndex.m_poolSz ; ++i)
|
||||||
|
writer.writeUint32Big(poolSkinIndex.m_poolToSkinIndex[i]);
|
||||||
}
|
}
|
||||||
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(outPath, inPath, mesh))
|
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(
|
||||||
|
outPath, inPath, mesh, poolSkinIndex))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,12 @@ struct CTweakPlayerGun : ITweakPlayerGun
|
||||||
Value<float> x18_;
|
Value<float> x18_;
|
||||||
Value<float> x1c_;
|
Value<float> x1c_;
|
||||||
Value<float> x20_;
|
Value<float> x20_;
|
||||||
Value<float> x24_;
|
Value<float> x24_aimVerticalSpeed;
|
||||||
Value<float> x28_;
|
Value<float> x28_aimHorizontalSpeed;
|
||||||
Value<float> x2c_;
|
Value<float> x2c_bombFuseTime;
|
||||||
Value<float> x30_;
|
Value<float> x30_bombDropDelayTime;
|
||||||
Value<float> x34_;
|
Value<float> x34_holoHoldTime;
|
||||||
Value<float> x38_;
|
Value<float> x38_gunTransformTime;
|
||||||
Value<float> x3c_gunHolsterTime;
|
Value<float> x3c_gunHolsterTime;
|
||||||
Value<float> x40_gunNotFiringTime;
|
Value<float> x40_gunNotFiringTime;
|
||||||
Value<float> x44_fixedVerticalAim;
|
Value<float> x44_fixedVerticalAim;
|
||||||
|
@ -53,12 +53,12 @@ struct CTweakPlayerGun : ITweakPlayerGun
|
||||||
x44_fixedVerticalAim = zeus::degToRad(x44_fixedVerticalAim);
|
x44_fixedVerticalAim = zeus::degToRad(x44_fixedVerticalAim);
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetX24() const { return x24_; }
|
float GetAimVerticalSpeed() const { return x24_aimVerticalSpeed; }
|
||||||
float GetX28() const { return x28_; }
|
float GetAimHorizontalSpeed() const { return x28_aimHorizontalSpeed; }
|
||||||
float GetX2c() const { return x2c_; }
|
float GetBombFuseTime() const { return x2c_bombFuseTime; }
|
||||||
float GetX30() const { return x30_; }
|
float GetBombDropDelayTime() const { return x30_bombDropDelayTime; }
|
||||||
float GetX34() const { return x34_; }
|
float GetHoloHoldTime() const { return x34_holoHoldTime; }
|
||||||
float GetX38() const { return x38_; }
|
float GetGunTransformTime() const { return x38_gunTransformTime; }
|
||||||
float GetGunHolsterTime() const { return x3c_gunHolsterTime; }
|
float GetGunHolsterTime() const { return x3c_gunHolsterTime; }
|
||||||
float GetGunNotFiringTime() const { return x40_gunNotFiringTime; }
|
float GetGunNotFiringTime() const { return x40_gunNotFiringTime; }
|
||||||
float GetFixedVerticalAim() const { return x44_fixedVerticalAim; }
|
float GetFixedVerticalAim() const { return x44_fixedVerticalAim; }
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "CSkinRules.hpp"
|
#include "CSkinRules.hpp"
|
||||||
#include "CToken.hpp"
|
#include "CToken.hpp"
|
||||||
|
#include "Graphics/CModel.hpp"
|
||||||
|
#include "CPoseAsTransforms.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -10,6 +12,37 @@ CSkinRules::CSkinRules(CInputStream& in)
|
||||||
x0_skinBanks.reserve(bankCount);
|
x0_skinBanks.reserve(bankCount);
|
||||||
for (u32 i=0 ; i<bankCount ; ++i)
|
for (u32 i=0 ; i<bankCount ; ++i)
|
||||||
x0_skinBanks.emplace_back(in);
|
x0_skinBanks.emplace_back(in);
|
||||||
|
|
||||||
|
u32 virtualBoneCount = in.readUint32Big();
|
||||||
|
m_virtualBones.reserve(virtualBoneCount);
|
||||||
|
for (u32 i=0 ; i<virtualBoneCount ; ++i)
|
||||||
|
m_virtualBones.emplace_back(in);
|
||||||
|
|
||||||
|
u32 poolSz = in.readUint32Big();
|
||||||
|
m_poolToSkinIdx.reserve(poolSz);
|
||||||
|
for (u32 i=0 ; i<poolSz ; ++i)
|
||||||
|
m_poolToSkinIdx.push_back(in.readUint32Big());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSkinRules::TransformVerticesCPU(std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vnOut,
|
||||||
|
const CPoseAsTransforms& pose, const CModel& model) const
|
||||||
|
{
|
||||||
|
vnOut.resize(m_poolToSkinIdx.size());
|
||||||
|
for (size_t i=0 ; i<m_poolToSkinIdx.size() ; ++i)
|
||||||
|
{
|
||||||
|
const CVirtualBone& vb = m_virtualBones[m_poolToSkinIdx[i]];
|
||||||
|
zeus::CVector3f origVertex = model.GetPoolVertex(i);
|
||||||
|
zeus::CVector3f vertex;
|
||||||
|
zeus::CVector3f origNormal = model.GetPoolNormal(i);
|
||||||
|
zeus::CVector3f normal;
|
||||||
|
for (const SSkinWeighting& w : vb.GetWeights())
|
||||||
|
{
|
||||||
|
const zeus::CTransform& xf = pose.GetRestToAccumTransform(w.m_id);
|
||||||
|
vertex += (xf * origVertex) * w.m_weight;
|
||||||
|
normal += (xf.basis.inverted().transposed() * origVertex) * w.m_weight;
|
||||||
|
}
|
||||||
|
vnOut[i] = std::make_pair(vertex, normal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
|
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef __URDE_CSKINRULES_HPP__
|
#ifndef __URDE_CSKINRULES_HPP__
|
||||||
#define __URDE_CSKINRULES_HPP__
|
#define __URDE_CSKINRULES_HPP__
|
||||||
|
|
||||||
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
#include "RetroTypes.hpp"
|
#include "RetroTypes.hpp"
|
||||||
#include "CSkinBank.hpp"
|
#include "CSkinBank.hpp"
|
||||||
#include "CFactoryMgr.hpp"
|
#include "CFactoryMgr.hpp"
|
||||||
|
@ -8,18 +9,48 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
class CPoseAsTransforms;
|
class CPoseAsTransforms;
|
||||||
|
class CModel;
|
||||||
|
|
||||||
|
struct SSkinWeighting
|
||||||
|
{
|
||||||
|
CSegId m_id;
|
||||||
|
float m_weight;
|
||||||
|
explicit SSkinWeighting(CInputStream& in)
|
||||||
|
: m_id(in), m_weight(in.readFloatBig()) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CVirtualBone
|
||||||
|
{
|
||||||
|
std::vector<SSkinWeighting> m_weights;
|
||||||
|
public:
|
||||||
|
explicit CVirtualBone(CInputStream& in)
|
||||||
|
{
|
||||||
|
u32 weightCount = in.readUint32Big();
|
||||||
|
m_weights.reserve(weightCount);
|
||||||
|
for (u32 i=0 ; i<weightCount ; ++i)
|
||||||
|
m_weights.emplace_back(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<SSkinWeighting>& GetWeights() const { return m_weights; }
|
||||||
|
};
|
||||||
|
|
||||||
class CSkinRules
|
class CSkinRules
|
||||||
{
|
{
|
||||||
std::vector<CSkinBank> x0_skinBanks;
|
std::vector<CSkinBank> x0_skinBanks;
|
||||||
|
//u32 x10_vertexCount;
|
||||||
|
//u32 x14_normalCount;
|
||||||
|
std::vector<CVirtualBone> m_virtualBones;
|
||||||
|
std::vector<u32> m_poolToSkinIdx;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CSkinRules(CInputStream& in);
|
explicit CSkinRules(CInputStream& in);
|
||||||
void BuildAccumulatedTransforms();
|
|
||||||
void GetBankTransforms(std::vector<const zeus::CTransform*>& out,
|
void GetBankTransforms(std::vector<const zeus::CTransform*>& out,
|
||||||
const CPoseAsTransforms& pose, int skinBankIdx) const
|
const CPoseAsTransforms& pose, int skinBankIdx) const
|
||||||
{
|
{ x0_skinBanks[skinBankIdx].GetBankTransforms(out, pose); }
|
||||||
x0_skinBanks[skinBankIdx].GetBankTransforms(out, pose);
|
|
||||||
}
|
void TransformVerticesCPU(std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vnOut,
|
||||||
|
const CPoseAsTransforms& pose, const CModel& model) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
|
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
|
||||||
|
|
|
@ -66,6 +66,7 @@ set(GRAPHICS_SOURCES
|
||||||
CPVSAreaSet.hpp CPVSAreaSet.cpp
|
CPVSAreaSet.hpp CPVSAreaSet.cpp
|
||||||
CGraphics.hpp CGraphics.cpp
|
CGraphics.hpp CGraphics.cpp
|
||||||
CSimpleShadow.hpp CSimpleShadow.cpp
|
CSimpleShadow.hpp CSimpleShadow.cpp
|
||||||
|
CModelPointSelector.hpp CModelPointSelector.cpp
|
||||||
Shaders/TShader.hpp Shaders/TMultiBlendShader.hpp Shaders/TShaderDecl.hpp Shaders/TMultiBlendShaderDecl.hpp
|
Shaders/TShader.hpp Shaders/TMultiBlendShader.hpp Shaders/TShaderDecl.hpp Shaders/TMultiBlendShaderDecl.hpp
|
||||||
Shaders/CLineRendererShaders.hpp Shaders/CLineRendererShaders.cpp Shaders/CLineRendererShadersGLSL.cpp
|
Shaders/CLineRendererShaders.hpp Shaders/CLineRendererShaders.cpp Shaders/CLineRendererShadersGLSL.cpp
|
||||||
Shaders/CTexturedQuadFilter.hpp Shaders/CTexturedQuadFilter.cpp Shaders/CTexturedQuadFilterGLSL.cpp
|
Shaders/CTexturedQuadFilter.hpp Shaders/CTexturedQuadFilter.cpp Shaders/CTexturedQuadFilterGLSL.cpp
|
||||||
|
|
|
@ -105,11 +105,6 @@ private:
|
||||||
const MaterialSet* x4_matSet;
|
const MaterialSet* x4_matSet;
|
||||||
int m_matSetIdx = -1;
|
int m_matSetIdx = -1;
|
||||||
const std::vector<std::shared_ptr<hecl::Runtime::ShaderPipelines>>* m_pipelines;
|
const std::vector<std::shared_ptr<hecl::Runtime::ShaderPipelines>>* m_pipelines;
|
||||||
boo::IVertexFormat* m_vtxFmt;
|
|
||||||
boo::IGraphicsBufferS* x8_vbo;
|
|
||||||
boo::IGraphicsBufferS* xc_ibo;
|
|
||||||
size_t m_weightVecCount;
|
|
||||||
size_t m_skinBankCount;
|
|
||||||
std::vector<TCachedToken<CTexture>> x1c_textures;
|
std::vector<TCachedToken<CTexture>> x1c_textures;
|
||||||
zeus::CAABox x20_aabb;
|
zeus::CAABox x20_aabb;
|
||||||
CBooSurface* x38_firstUnsortedSurface = nullptr;
|
CBooSurface* x38_firstUnsortedSurface = nullptr;
|
||||||
|
@ -135,9 +130,18 @@ private:
|
||||||
boo::GraphicsDataToken m_gfxToken;
|
boo::GraphicsDataToken m_gfxToken;
|
||||||
boo::IGraphicsBufferD* m_uniformBuffer;
|
boo::IGraphicsBufferD* m_uniformBuffer;
|
||||||
std::vector<std::vector<boo::IShaderDataBinding*>> m_shaderDataBindings;
|
std::vector<std::vector<boo::IShaderDataBinding*>> m_shaderDataBindings;
|
||||||
|
boo::IVertexFormat* m_dynamicVtxFmt = nullptr;
|
||||||
|
boo::IGraphicsBufferD* m_dynamicVbo = nullptr;
|
||||||
|
|
||||||
|
boo::IGraphicsBuffer* GetBooVBO(const CBooModel& model, boo::IGraphicsDataFactory::Context& ctx);
|
||||||
|
boo::IVertexFormat* GetBooVtxFmt(const CBooModel& model, boo::IGraphicsDataFactory::Context& ctx);
|
||||||
};
|
};
|
||||||
std::vector<ModelInstance> m_instances;
|
std::vector<ModelInstance> m_instances;
|
||||||
|
|
||||||
|
boo::IVertexFormat* m_staticVtxFmt = nullptr;
|
||||||
|
boo::IGraphicsBufferS* m_staticVbo = nullptr;
|
||||||
|
boo::IGraphicsBufferS* m_staticIbo = nullptr;
|
||||||
|
|
||||||
boo::ITexture* m_txtrOverrides[8] = {};
|
boo::ITexture* m_txtrOverrides[8] = {};
|
||||||
|
|
||||||
ModelInstance* PushNewModelInstance();
|
ModelInstance* PushNewModelInstance();
|
||||||
|
@ -156,7 +160,7 @@ public:
|
||||||
~CBooModel();
|
~CBooModel();
|
||||||
CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
|
CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
|
||||||
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
|
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
|
||||||
size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb, u8 renderMask,
|
const zeus::CAABox& aabb, u8 renderMask,
|
||||||
int numInsts, boo::ITexture* txtrOverrides[8]);
|
int numInsts, boo::ITexture* txtrOverrides[8]);
|
||||||
|
|
||||||
static void MakeTexturesFromMats(const MaterialSet& matSet,
|
static void MakeTexturesFromMats(const MaterialSet& matSet,
|
||||||
|
@ -173,9 +177,9 @@ public:
|
||||||
void UnlockTextures() const;
|
void UnlockTextures() const;
|
||||||
void Touch(int shaderIdx) const;
|
void Touch(int shaderIdx) const;
|
||||||
void VerifyCurrentShader(int shaderIdx);
|
void VerifyCurrentShader(int shaderIdx);
|
||||||
void UpdateUniformData(const CModelFlags& flags,
|
boo::IGraphicsBufferD* UpdateUniformData(const CModelFlags& flags,
|
||||||
const CSkinRules* cskr,
|
const CSkinRules* cskr,
|
||||||
const CPoseAsTransforms* pose) const;
|
const CPoseAsTransforms* pose) const;
|
||||||
void DrawAlpha(const CModelFlags& flags,
|
void DrawAlpha(const CModelFlags& flags,
|
||||||
const CSkinRules* cskr,
|
const CSkinRules* cskr,
|
||||||
const CPoseAsTransforms* pose) const;
|
const CPoseAsTransforms* pose) const;
|
||||||
|
@ -224,12 +228,11 @@ class CModel
|
||||||
|
|
||||||
/* urde addition: boo! */
|
/* urde addition: boo! */
|
||||||
boo::GraphicsDataToken m_gfxToken;
|
boo::GraphicsDataToken m_gfxToken;
|
||||||
boo::IGraphicsBufferS* m_vbo;
|
boo::IVertexFormat* m_staticVtxFmt = nullptr;
|
||||||
|
boo::IGraphicsBufferS* m_staticVbo = nullptr;
|
||||||
|
hecl::HMDLMeta m_hmdlMeta;
|
||||||
|
std::unique_ptr<uint8_t[]> m_dynamicVertexData;
|
||||||
boo::IGraphicsBufferS* m_ibo;
|
boo::IGraphicsBufferS* m_ibo;
|
||||||
boo::IVertexFormat* m_vtxFmt;
|
|
||||||
|
|
||||||
u32 m_weightVecCount;
|
|
||||||
u32 m_skinBankCount;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
|
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
|
||||||
|
@ -246,6 +249,13 @@ public:
|
||||||
const CBooModel& GetInstance() const {return *x28_modelInst;}
|
const CBooModel& GetInstance() const {return *x28_modelInst;}
|
||||||
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts, boo::ITexture* txtrOverrides[8] = nullptr);
|
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts, boo::ITexture* txtrOverrides[8] = nullptr);
|
||||||
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
|
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
|
||||||
|
|
||||||
|
size_t GetPoolVertexOffset(size_t idx) const;
|
||||||
|
zeus::CVector3f GetPoolVertex(size_t idx) const;
|
||||||
|
size_t GetPoolNormalOffset(size_t idx) const;
|
||||||
|
zeus::CVector3f GetPoolNormal(size_t idx) const;
|
||||||
|
void ApplyVerticesCPU(boo::IGraphicsBufferD* vertBuf,
|
||||||
|
const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
|
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
|
||||||
|
|
|
@ -135,12 +135,12 @@ CBooModel::~CBooModel()
|
||||||
|
|
||||||
CBooModel::CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
|
CBooModel::CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
|
||||||
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
|
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
|
||||||
size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb, u8 renderMask,
|
const zeus::CAABox& aabb, u8 renderMask,
|
||||||
int instCount, boo::ITexture* txtrOverrides[8])
|
int numInsts, boo::ITexture* txtrOverrides[8])
|
||||||
: m_model(token), x0_surfaces(surfaces), x4_matSet(&shader.m_matSet), m_matSetIdx(shader.m_matSetIdx),
|
: m_model(token), x0_surfaces(surfaces), x4_matSet(&shader.m_matSet), m_matSetIdx(shader.m_matSetIdx),
|
||||||
m_pipelines(&shader.m_shaders), m_vtxFmt(vtxFmt), x8_vbo(vbo), xc_ibo(ibo), m_weightVecCount(weightVecCount),
|
m_pipelines(&shader.m_shaders), x1c_textures(shader.x0_textures), x20_aabb(aabb),
|
||||||
m_skinBankCount(skinBankCount), x1c_textures(shader.x0_textures), x20_aabb(aabb),
|
x40_24_texturesLoaded(false), x40_25_modelVisible(0), x41_mask(renderMask),
|
||||||
x40_24_texturesLoaded(false), x40_25_modelVisible(0), x41_mask(renderMask)
|
m_staticVtxFmt(vtxFmt), m_staticVbo(vbo), m_staticIbo(ibo)
|
||||||
{
|
{
|
||||||
if (txtrOverrides)
|
if (txtrOverrides)
|
||||||
for (int i=0 ; i<8 ; ++i)
|
for (int i=0 ; i<8 ; ++i)
|
||||||
|
@ -174,11 +174,41 @@ CBooModel::CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_instances.reserve(instCount);
|
m_instances.reserve(numInsts);
|
||||||
for (int i=0 ; i<instCount ; ++i)
|
for (int i=0 ; i<numInsts ; ++i)
|
||||||
PushNewModelInstance();
|
PushNewModelInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boo::IGraphicsBuffer* CBooModel::ModelInstance::GetBooVBO(const CBooModel& model,
|
||||||
|
boo::IGraphicsDataFactory::Context& ctx)
|
||||||
|
{
|
||||||
|
if (model.m_staticVbo)
|
||||||
|
return model.m_staticVbo;
|
||||||
|
if (!m_dynamicVbo && model.m_model)
|
||||||
|
{
|
||||||
|
const CModel& parent = *model.m_model;
|
||||||
|
m_dynamicVbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex,
|
||||||
|
parent.m_hmdlMeta.vertStride, parent.m_hmdlMeta.vertCount);
|
||||||
|
m_dynamicVbo->load(parent.m_dynamicVertexData.get(),
|
||||||
|
parent.m_hmdlMeta.vertStride * parent.m_hmdlMeta.vertCount);
|
||||||
|
}
|
||||||
|
return m_dynamicVbo;
|
||||||
|
}
|
||||||
|
|
||||||
|
boo::IVertexFormat* CBooModel::ModelInstance::GetBooVtxFmt(const CBooModel& model,
|
||||||
|
boo::IGraphicsDataFactory::Context& ctx)
|
||||||
|
{
|
||||||
|
if (model.m_staticVtxFmt)
|
||||||
|
return model.m_staticVtxFmt;
|
||||||
|
if (!m_dynamicVtxFmt && model.m_model)
|
||||||
|
{
|
||||||
|
const CModel& parent = *model.m_model;
|
||||||
|
m_dynamicVtxFmt = hecl::Runtime::HMDLData::NewVertexFormat(ctx, parent.m_hmdlMeta,
|
||||||
|
GetBooVBO(model, ctx), parent.m_ibo);
|
||||||
|
}
|
||||||
|
return m_dynamicVtxFmt;
|
||||||
|
}
|
||||||
|
|
||||||
CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
{
|
{
|
||||||
if (!x40_24_texturesLoaded)
|
if (!x40_24_texturesLoaded)
|
||||||
|
@ -188,6 +218,13 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
Log.report(logvisor::Fatal, "Model buffer overflow");
|
Log.report(logvisor::Fatal, "Model buffer overflow");
|
||||||
m_instances.emplace_back();
|
m_instances.emplace_back();
|
||||||
ModelInstance& newInst = m_instances.back();
|
ModelInstance& newInst = m_instances.back();
|
||||||
|
size_t skinBankCount = 0;
|
||||||
|
size_t weightVecCount = 0;
|
||||||
|
if (const CModel* model = m_model.GetObj())
|
||||||
|
{
|
||||||
|
skinBankCount = model->m_hmdlMeta.bankCount;
|
||||||
|
weightVecCount = model->m_hmdlMeta.weightCount;
|
||||||
|
}
|
||||||
|
|
||||||
newInst.m_gfxToken = CGraphics::CommitResources(
|
newInst.m_gfxToken = CGraphics::CommitResources(
|
||||||
[&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
[&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
|
@ -195,8 +232,8 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
/* Determine space required by uniform buffer */
|
/* Determine space required by uniform buffer */
|
||||||
std::vector<size_t> skinOffs;
|
std::vector<size_t> skinOffs;
|
||||||
std::vector<size_t> skinSizes;
|
std::vector<size_t> skinSizes;
|
||||||
skinOffs.reserve(std::max(size_t(1), m_skinBankCount));
|
skinOffs.reserve(std::max(size_t(1), skinBankCount));
|
||||||
skinSizes.reserve(std::max(size_t(1), m_skinBankCount));
|
skinSizes.reserve(std::max(size_t(1), skinBankCount));
|
||||||
|
|
||||||
std::vector<size_t> uvOffs;
|
std::vector<size_t> uvOffs;
|
||||||
std::vector<size_t> uvSizes;
|
std::vector<size_t> uvSizes;
|
||||||
|
@ -205,12 +242,12 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
|
|
||||||
/* Vert transform matrices */
|
/* Vert transform matrices */
|
||||||
size_t uniBufSize = 0;
|
size_t uniBufSize = 0;
|
||||||
if (m_skinBankCount)
|
if (skinBankCount)
|
||||||
{
|
{
|
||||||
/* Skinned */
|
/* Skinned */
|
||||||
for (size_t i=0 ; i<m_skinBankCount ; ++i)
|
for (size_t i=0 ; i<skinBankCount ; ++i)
|
||||||
{
|
{
|
||||||
size_t thisSz = ROUND_UP_256(sizeof(zeus::CMatrix4f) * (2 * m_weightVecCount * 4 + 1));
|
size_t thisSz = ROUND_UP_256(sizeof(zeus::CMatrix4f) * (2 * weightVecCount * 4 + 1));
|
||||||
skinOffs.push_back(uniBufSize);
|
skinOffs.push_back(uniBufSize);
|
||||||
skinSizes.push_back(thisSz);
|
skinSizes.push_back(thisSz);
|
||||||
uniBufSize += thisSz;
|
uniBufSize += thisSz;
|
||||||
|
@ -299,7 +336,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
}
|
}
|
||||||
texs[7] = g_Renderer->x220_sphereRamp;
|
texs[7] = g_Renderer->x220_sphereRamp;
|
||||||
|
|
||||||
if (m_skinBankCount)
|
if (skinBankCount)
|
||||||
{
|
{
|
||||||
thisOffs[0] = skinOffs[surf.m_data.skinMtxBankIdx];
|
thisOffs[0] = skinOffs[surf.m_data.skinMtxBankIdx];
|
||||||
thisSizes[0] = skinSizes[surf.m_data.skinMtxBankIdx];
|
thisSizes[0] = skinSizes[surf.m_data.skinMtxBankIdx];
|
||||||
|
@ -361,9 +398,9 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||||
ltexs = texs;
|
ltexs = texs;
|
||||||
}
|
}
|
||||||
extendeds.push_back(
|
extendeds.push_back(
|
||||||
ctx.newShaderDataBinding(pipeline, m_vtxFmt,
|
ctx.newShaderDataBinding(pipeline, newInst.GetBooVtxFmt(*this, ctx),
|
||||||
x8_vbo, nullptr, xc_ibo, 4, bufs, stages,
|
newInst.GetBooVBO(*this, ctx), nullptr, m_staticIbo, 4, bufs,
|
||||||
thisOffs, thisSizes, texCount, ltexs, nullptr, nullptr));
|
stages, thisOffs, thisSizes, texCount, ltexs, nullptr, nullptr));
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -695,16 +732,24 @@ void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::UpdateUniformData(const CModelFlags& flags,
|
boo::IGraphicsBufferD* CBooModel::UpdateUniformData(const CModelFlags& flags,
|
||||||
const CSkinRules* cskr,
|
const CSkinRules* cskr,
|
||||||
const CPoseAsTransforms* pose) const
|
const CPoseAsTransforms* pose) const
|
||||||
{
|
{
|
||||||
|
size_t skinBankCount = 0;
|
||||||
|
size_t weightVecCount = 0;
|
||||||
|
if (const CModel* model = m_model.GetObj())
|
||||||
|
{
|
||||||
|
skinBankCount = model->m_hmdlMeta.bankCount;
|
||||||
|
weightVecCount = model->m_hmdlMeta.weightCount;
|
||||||
|
}
|
||||||
|
|
||||||
const ModelInstance* inst;
|
const ModelInstance* inst;
|
||||||
if (m_instances.size() <= m_uniUpdateCount)
|
if (m_instances.size() <= m_uniUpdateCount)
|
||||||
{
|
{
|
||||||
inst = const_cast<CBooModel*>(this)->PushNewModelInstance();
|
inst = const_cast<CBooModel*>(this)->PushNewModelInstance();
|
||||||
if (!inst)
|
if (!inst)
|
||||||
return;
|
return nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
inst = &m_instances[m_uniUpdateCount];
|
inst = &m_instances[m_uniUpdateCount];
|
||||||
|
@ -713,13 +758,13 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
|
||||||
u8* dataOut = reinterpret_cast<u8*>(inst->m_uniformBuffer->map(m_uniformDataSize));
|
u8* dataOut = reinterpret_cast<u8*>(inst->m_uniformBuffer->map(m_uniformDataSize));
|
||||||
u8* dataCur = dataOut;
|
u8* dataCur = dataOut;
|
||||||
|
|
||||||
if (m_skinBankCount)
|
if (skinBankCount)
|
||||||
{
|
{
|
||||||
/* Skinned */
|
/* Skinned */
|
||||||
std::vector<const zeus::CTransform*> bankTransforms;
|
std::vector<const zeus::CTransform*> bankTransforms;
|
||||||
size_t weightCount = m_weightVecCount * 4;
|
size_t weightCount = weightVecCount * 4;
|
||||||
bankTransforms.reserve(weightCount);
|
bankTransforms.reserve(weightCount);
|
||||||
for (size_t i=0 ; i<m_skinBankCount ; ++i)
|
for (size_t i=0 ; i<skinBankCount ; ++i)
|
||||||
{
|
{
|
||||||
if (cskr && pose)
|
if (cskr && pose)
|
||||||
{
|
{
|
||||||
|
@ -844,6 +889,7 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
inst->m_uniformBuffer->unmap();
|
inst->m_uniformBuffer->unmap();
|
||||||
|
return inst->m_dynamicVbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooModel::DrawAlpha(const CModelFlags& flags,
|
void CBooModel::DrawAlpha(const CModelFlags& flags,
|
||||||
|
@ -879,10 +925,10 @@ void CBooModel::Draw(const CModelFlags& flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u8* MemoryFromPartData(const u8*& dataCur, const s32*& secSizeCur)
|
static const u8* MemoryFromPartData(const u8*& dataCur, const u32*& secSizeCur)
|
||||||
{
|
{
|
||||||
const u8* ret;
|
const u8* ret;
|
||||||
if (*secSizeCur)
|
if (*secSizeCur != 0)
|
||||||
ret = dataCur;
|
ret = dataCur;
|
||||||
else
|
else
|
||||||
ret = nullptr;
|
ret = nullptr;
|
||||||
|
@ -897,7 +943,7 @@ std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx, int subInsts,
|
||||||
if (shaderIdx >= x18_matSets.size())
|
if (shaderIdx >= x18_matSets.size())
|
||||||
shaderIdx = 0;
|
shaderIdx = 0;
|
||||||
return std::make_unique<CBooModel>(m_selfToken, &x8_surfaces, x18_matSets[shaderIdx],
|
return std::make_unique<CBooModel>(m_selfToken, &x8_surfaces, x18_matSets[shaderIdx],
|
||||||
m_vtxFmt, m_vbo, m_ibo, m_weightVecCount, m_skinBankCount,
|
m_staticVtxFmt, m_staticVbo, m_ibo,
|
||||||
m_aabb, (m_flags & 0x2) != 0, subInsts, txtrOverrides);
|
m_aabb, (m_flags & 0x2) != 0, subInsts, txtrOverrides);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,7 +962,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
|
||||||
u32 matSetCount = hecl::SBig(*reinterpret_cast<u32*>(data.get() + 0x28));
|
u32 matSetCount = hecl::SBig(*reinterpret_cast<u32*>(data.get() + 0x28));
|
||||||
x18_matSets.reserve(matSetCount);
|
x18_matSets.reserve(matSetCount);
|
||||||
const u8* dataCur = data.get() + ROUND_UP_32(0x2c + secCount * 4);
|
const u8* dataCur = data.get() + ROUND_UP_32(0x2c + secCount * 4);
|
||||||
const s32* secSizeCur = reinterpret_cast<const s32*>(data.get() + 0x2c);
|
const u32* secSizeCur = reinterpret_cast<const u32*>(data.get() + 0x2c);
|
||||||
for (u32 i=0 ; i<matSetCount ; ++i)
|
for (u32 i=0 ; i<matSetCount ; ++i)
|
||||||
{
|
{
|
||||||
u32 matSetSz = hecl::SBig(*secSizeCur);
|
u32 matSetSz = hecl::SBig(*secSizeCur);
|
||||||
|
@ -928,15 +974,12 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
|
||||||
CBooModel::MakeTexturesFromMats(shader.m_matSet, shader.x0_textures, *store);
|
CBooModel::MakeTexturesFromMats(shader.m_matSet, shader.x0_textures, *store);
|
||||||
}
|
}
|
||||||
|
|
||||||
hecl::HMDLMeta hmdlMeta;
|
|
||||||
{
|
{
|
||||||
u32 hmdlSz = hecl::SBig(*secSizeCur);
|
u32 hmdlSz = hecl::SBig(*secSizeCur);
|
||||||
const u8* hmdlMetadata = MemoryFromPartData(dataCur, secSizeCur);
|
const u8* hmdlMetadata = MemoryFromPartData(dataCur, secSizeCur);
|
||||||
athena::io::MemoryReader r(hmdlMetadata, hmdlSz);
|
athena::io::MemoryReader r(hmdlMetadata, hmdlSz);
|
||||||
hmdlMeta.read(r);
|
m_hmdlMeta.read(r);
|
||||||
}
|
}
|
||||||
m_weightVecCount = hmdlMeta.weightCount;
|
|
||||||
m_skinBankCount = hmdlMeta.bankCount;
|
|
||||||
|
|
||||||
const u8* vboData = MemoryFromPartData(dataCur, secSizeCur);
|
const u8* vboData = MemoryFromPartData(dataCur, secSizeCur);
|
||||||
const u8* iboData = MemoryFromPartData(dataCur, secSizeCur);
|
const u8* iboData = MemoryFromPartData(dataCur, secSizeCur);
|
||||||
|
@ -955,8 +998,8 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
|
||||||
else
|
else
|
||||||
reflectionType = hecl::Backend::ReflectionType::None;
|
reflectionType = hecl::Backend::ReflectionType::None;
|
||||||
hecl::Runtime::ShaderTag tag(mat.heclIr,
|
hecl::Runtime::ShaderTag tag(mat.heclIr,
|
||||||
hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount,
|
m_hmdlMeta.colorCount, m_hmdlMeta.uvCount, m_hmdlMeta.weightCount,
|
||||||
hmdlMeta.weightCount * 4, 8, boo::Primitive(hmdlMeta.topology),
|
m_hmdlMeta.weightCount * 4, 8, boo::Primitive(m_hmdlMeta.topology),
|
||||||
reflectionType, true, true, true);
|
reflectionType, true, true, true);
|
||||||
matSet.m_shaders.push_back(CModelShaders::g_ModelShaders->buildExtendedShader
|
matSet.m_shaders.push_back(CModelShaders::g_ModelShaders->buildExtendedShader
|
||||||
(tag, mat.heclIr, "CMDL", *CGraphics::g_BooFactory));
|
(tag, mat.heclIr, "CMDL", *CGraphics::g_BooFactory));
|
||||||
|
@ -965,9 +1008,23 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
|
||||||
|
|
||||||
m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||||
{
|
{
|
||||||
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, vboData, hmdlMeta.vertStride, hmdlMeta.vertCount);
|
if (!m_hmdlMeta.bankCount)
|
||||||
m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, iboData, 4, hmdlMeta.indexCount);
|
{
|
||||||
m_vtxFmt = hecl::Runtime::HMDLData::NewVertexFormat(ctx, hmdlMeta, m_vbo, m_ibo);
|
/* Non-skinned models use static vertex buffers shared with CBooModel instances */
|
||||||
|
m_staticVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, vboData,
|
||||||
|
m_hmdlMeta.vertStride, m_hmdlMeta.vertCount);
|
||||||
|
m_staticVtxFmt = hecl::Runtime::HMDLData::NewVertexFormat(ctx, m_hmdlMeta, m_staticVbo, m_ibo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Skinned models use per-instance dynamic buffers for vertex manipulation effects */
|
||||||
|
size_t vboSz = m_hmdlMeta.vertStride * m_hmdlMeta.vertCount;
|
||||||
|
m_dynamicVertexData.reset(new uint8_t[vboSz]);
|
||||||
|
memmove(m_dynamicVertexData.get(), vboData, vboSz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Index buffer is always static */
|
||||||
|
m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, iboData, 4, m_hmdlMeta.indexCount);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1042,6 +1099,46 @@ bool CModel::IsLoaded(int shaderIdx) const
|
||||||
return loaded;
|
return loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t CModel::GetPoolVertexOffset(size_t idx) const
|
||||||
|
{
|
||||||
|
return m_hmdlMeta.vertStride * idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f CModel::GetPoolVertex(size_t idx) const
|
||||||
|
{
|
||||||
|
auto* floats = reinterpret_cast<const float*>(m_dynamicVertexData.get() + GetPoolVertexOffset(idx));
|
||||||
|
return {floats[0], floats[1], floats[2]};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CModel::GetPoolNormalOffset(size_t idx) const
|
||||||
|
{
|
||||||
|
return m_hmdlMeta.vertStride * idx + 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f CModel::GetPoolNormal(size_t idx) const
|
||||||
|
{
|
||||||
|
auto* floats = reinterpret_cast<const float*>(m_dynamicVertexData.get() + GetPoolNormalOffset(idx));
|
||||||
|
return {floats[0], floats[1], floats[2]};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CModel::ApplyVerticesCPU(boo::IGraphicsBufferD* vertBuf,
|
||||||
|
const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn) const
|
||||||
|
{
|
||||||
|
u8* data = reinterpret_cast<u8*>(vertBuf->map(m_hmdlMeta.vertStride * m_hmdlMeta.vertCount));
|
||||||
|
for (u32 i=0 ; i<std::min(u32(vn.size()), m_hmdlMeta.vertCount) ; ++i)
|
||||||
|
{
|
||||||
|
const std::pair<zeus::CVector3f, zeus::CVector3f>& avn = vn[i];
|
||||||
|
float* floats = reinterpret_cast<float*>(data + GetPoolVertexOffset(i));
|
||||||
|
floats[0] = avn.first.x;
|
||||||
|
floats[1] = avn.first.y;
|
||||||
|
floats[2] = avn.first.z;
|
||||||
|
floats[3] = avn.second.x;
|
||||||
|
floats[4] = avn.second.y;
|
||||||
|
floats[5] = avn.second.z;
|
||||||
|
}
|
||||||
|
vertBuf->unmap();
|
||||||
|
}
|
||||||
|
|
||||||
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
|
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
|
||||||
std::unique_ptr<u8[]>&& in, u32 len,
|
std::unique_ptr<u8[]>&& in, u32 len,
|
||||||
const urde::CVParamTransfer& vparms,
|
const urde::CVParamTransfer& vparms,
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include "CModelPointSelector.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
CModelPointSelector::CModelPointSelector(const zeus::CVector3f& scale, int, int, float, float)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CModelPointSelector::GeneratePoints(const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef URDE_CMODELPOINTSELECTOR_HPP
|
||||||
|
#define URDE_CMODELPOINTSELECTOR_HPP
|
||||||
|
|
||||||
|
#include "RetroTypes.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
class CModelPointSelector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CModelPointSelector(const zeus::CVector3f& scale, int, int, float, float);
|
||||||
|
void GeneratePoints(const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // URDE_CMODELPOINTSELECTOR_HPP
|
|
@ -1,5 +1,6 @@
|
||||||
#include "CSkinnedModel.hpp"
|
#include "CSkinnedModel.hpp"
|
||||||
#include "Character/CSkinRules.hpp"
|
#include "Character/CSkinRules.hpp"
|
||||||
|
#include "CVertexMorphEffect.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -35,7 +36,20 @@ void CSkinnedModel::Calculate(const CPoseAsTransforms& pose,
|
||||||
const rstl::optional_object<CVertexMorphEffect>& morphEffect,
|
const rstl::optional_object<CVertexMorphEffect>& morphEffect,
|
||||||
const float* morphMagnitudes)
|
const float* morphMagnitudes)
|
||||||
{
|
{
|
||||||
m_modelInst->UpdateUniformData(drawFlags, x10_skinRules.GetObj(), &pose);
|
if (morphEffect || g_PointGenFunc)
|
||||||
|
{
|
||||||
|
boo::IGraphicsBufferD* vertBuf = m_modelInst->UpdateUniformData(drawFlags, nullptr, nullptr);
|
||||||
|
x10_skinRules->TransformVerticesCPU(m_vertWorkspace, pose, *x4_model);
|
||||||
|
if (morphEffect)
|
||||||
|
morphEffect->MorphVertices(m_vertWorkspace, morphMagnitudes, x10_skinRules, pose);
|
||||||
|
if (g_PointGenFunc)
|
||||||
|
g_PointGenFunc(g_PointGenCtx, m_vertWorkspace);
|
||||||
|
x4_model->ApplyVerticesCPU(vertBuf, m_vertWorkspace);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_modelInst->UpdateUniformData(drawFlags, x10_skinRules.GetObj(), &pose);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSkinnedModel::Draw(const CModelFlags& drawFlags) const
|
void CSkinnedModel::Draw(const CModelFlags& drawFlags) const
|
||||||
|
|
|
@ -21,6 +21,7 @@ class CSkinnedModel
|
||||||
TLockedToken<CModel> x4_model;
|
TLockedToken<CModel> x4_model;
|
||||||
TLockedToken<CSkinRules> x10_skinRules;
|
TLockedToken<CSkinRules> x10_skinRules;
|
||||||
TLockedToken<CCharLayoutInfo> x1c_layoutInfo;
|
TLockedToken<CCharLayoutInfo> x1c_layoutInfo;
|
||||||
|
std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>> m_vertWorkspace;
|
||||||
public:
|
public:
|
||||||
enum class EDataOwnership
|
enum class EDataOwnership
|
||||||
{
|
{
|
||||||
|
@ -45,7 +46,7 @@ public:
|
||||||
const float* morphMagnitudes);
|
const float* morphMagnitudes);
|
||||||
void Draw(const CModelFlags& drawFlags) const;
|
void Draw(const CModelFlags& drawFlags) const;
|
||||||
|
|
||||||
typedef void(*FPointGenerator)(void* item, const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1);
|
typedef void(*FPointGenerator)(void* item, const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn);
|
||||||
static void SetPointGeneratorFunc(void* ctx, FPointGenerator func)
|
static void SetPointGeneratorFunc(void* ctx, FPointGenerator func)
|
||||||
{
|
{
|
||||||
g_PointGenFunc = func;
|
g_PointGenFunc = func;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "CVertexMorphEffect.hpp"
|
||||||
|
#include "Character/CSkinRules.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
void CVertexMorphEffect::MorphVertices(std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn,
|
||||||
|
const float* magnitudes, const TLockedToken<CSkinRules>& skinRules,
|
||||||
|
const CPoseAsTransforms& pose) const
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,19 @@
|
||||||
#ifndef __URDE_CVERTEXMORPHEFFECT_HPP__
|
#ifndef __URDE_CVERTEXMORPHEFFECT_HPP__
|
||||||
#define __URDE_CVERTEXMORPHEFFECT_HPP__
|
#define __URDE_CVERTEXMORPHEFFECT_HPP__
|
||||||
|
|
||||||
|
#include "CToken.hpp"
|
||||||
|
#include "Character/CPoseAsTransforms.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
class CSkinRules;
|
||||||
|
|
||||||
class CVertexMorphEffect
|
class CVertexMorphEffect
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
void MorphVertices(std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn,
|
||||||
|
const float* magnitudes, const TLockedToken<CSkinRules>& skinRules,
|
||||||
|
const CPoseAsTransforms& pose) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "CAuxWeapon.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
CAuxWeapon::CAuxWeapon(TUniqueId id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ namespace urde
|
||||||
class CAuxWeapon
|
class CAuxWeapon
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CAuxWeapon(TUniqueId id);
|
explicit CAuxWeapon(TUniqueId id);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "CGunMotion.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
CGunMotion::CGunMotion(CAssetId, const zeus::CVector3f& vec)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ class CGunMotion
|
||||||
CModelData x0_modelData;
|
CModelData x0_modelData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGunMotion(u32, const zeus::CVector3f& vec);
|
CGunMotion(CAssetId, const zeus::CVector3f& vec);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,21 +5,32 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static const zeus::CVector3f sGunScale(2.f);
|
||||||
|
|
||||||
CPlayerGun::CPlayerGun(TUniqueId id)
|
CPlayerGun::CPlayerGun(TUniqueId id)
|
||||||
: x0_lights(8, zeus::CVector3f{-30.f, 0.f, 30.f}, 4, 4, 0, 0, 0, 0.1f), x538_thisId(id),
|
: x0_lights(8, zeus::CVector3f{-30.f, 0.f, 30.f}, 4, 4, 0, 0, 0, 0.1f), x538_thisId(id),
|
||||||
x550_camBob(CPlayerCameraBob::ECameraBobType::One,
|
x550_camBob(CPlayerCameraBob::ECameraBobType::One,
|
||||||
zeus::CVector2f(0.071f, 0.141f), 0.47f),
|
zeus::CVector2f(CPlayerCameraBob::kCameraBobExtentX, CPlayerCameraBob::kCameraBobExtentY),
|
||||||
x678_morph(g_tweakPlayerGun->GetX38(), g_tweakPlayerGun->GetX34())
|
CPlayerCameraBob::kCameraBobPeriod),
|
||||||
|
x678_morph(g_tweakPlayerGun->GetGunTransformTime(), g_tweakPlayerGun->GetHoloHoldTime()),
|
||||||
|
x6c8_(zeus::CVector3f(-0.29329199f, 0.f, -0.2481945f),
|
||||||
|
zeus::CVector3f(0.29329199f, 1.292392f, 0.2481945f)),
|
||||||
|
x6e0_rightHandModel(CAnimRes(g_tweakGunRes->xc_rightHand, 0, zeus::CVector3f(3.f), 0, true))
|
||||||
{
|
{
|
||||||
x354_ = g_tweakPlayerGun->GetX2c();
|
x354_bombFuseTime = g_tweakPlayerGun->GetBombFuseTime();
|
||||||
x358_ = g_tweakPlayerGun->GetX30();
|
x358_bombDropDelayTime = g_tweakPlayerGun->GetBombDropDelayTime();
|
||||||
x668_ = g_tweakPlayerGun->GetX24();
|
x668_aimVerticalSpeed = g_tweakPlayerGun->GetAimVerticalSpeed();
|
||||||
x66c_ = g_tweakPlayerGun->GetX28();
|
x66c_aimHorizontalSpeed = g_tweakPlayerGun->GetAimHorizontalSpeed();
|
||||||
|
|
||||||
|
x73c_gunMotion = std::make_unique<CGunMotion>(g_tweakGunRes->x4_gunMotion, sGunScale);
|
||||||
|
x740_grappleArm = std::make_unique<CGrappleArm>(sGunScale);
|
||||||
|
x744_auxWeapon = std::make_unique<CAuxWeapon>(id);
|
||||||
|
|
||||||
|
|
||||||
x832_31_ = true;
|
x832_31_ = true;
|
||||||
x833_24_isFidgeting = true;
|
x833_24_isFidgeting = true;
|
||||||
x833_30_ = true;
|
x833_30_ = true;
|
||||||
x6e0_.SetSortThermal(true);
|
x6e0_rightHandModel.SetSortThermal(true);
|
||||||
|
|
||||||
/* TODO: Finish */
|
/* TODO: Finish */
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "Character/CModelData.hpp"
|
#include "Character/CModelData.hpp"
|
||||||
#include "World/CWorldShadow.hpp"
|
#include "World/CWorldShadow.hpp"
|
||||||
#include "World/ScriptObjectSupport.hpp"
|
#include "World/ScriptObjectSupport.hpp"
|
||||||
|
#include "Graphics/CModelPointSelector.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -40,10 +41,10 @@ private:
|
||||||
class CGunMorph
|
class CGunMorph
|
||||||
{
|
{
|
||||||
float x0_ = 0.f;
|
float x0_ = 0.f;
|
||||||
float x4_;
|
float x4_gunTransformTime;
|
||||||
float x8_ = 0.f;
|
float x8_ = 0.f;
|
||||||
float xc_ = 0.1f;
|
float xc_ = 0.1f;
|
||||||
float x10_;
|
float x10_holoHoldTime;
|
||||||
float x14_ = 2.f;
|
float x14_ = 2.f;
|
||||||
float x18_transitionFactor = 1.f;
|
float x18_transitionFactor = 1.f;
|
||||||
u32 x1c_ = 2;
|
u32 x1c_ = 2;
|
||||||
|
@ -60,8 +61,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGunMorph(float a, float b)
|
CGunMorph(float gunTransformTime, float holoHoldTime)
|
||||||
: x4_(a), x10_(std::fabs(b)) {}
|
: x4_gunTransformTime(gunTransformTime), x10_holoHoldTime(std::fabs(holoHoldTime)) {}
|
||||||
float GetTransitionFactor() const { return x18_transitionFactor; }
|
float GetTransitionFactor() const { return x18_transitionFactor; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -100,8 +101,8 @@ private:
|
||||||
float x348_ = 0.f;
|
float x348_ = 0.f;
|
||||||
float x34c_ = 0.f;
|
float x34c_ = 0.f;
|
||||||
float x350_ = 0.f;
|
float x350_ = 0.f;
|
||||||
float x354_;
|
float x354_bombFuseTime;
|
||||||
float x358_;
|
float x358_bombDropDelayTime;
|
||||||
float x35c_bombTime = 0.f;
|
float x35c_bombTime = 0.f;
|
||||||
float x360_ = 0.f;
|
float x360_ = 0.f;
|
||||||
float x364_ = 0.f;
|
float x364_ = 0.f;
|
||||||
|
@ -140,8 +141,8 @@ private:
|
||||||
float x65c_ = 0.f;
|
float x65c_ = 0.f;
|
||||||
float x660_ = 0.f;
|
float x660_ = 0.f;
|
||||||
float x664_ = 0.f;
|
float x664_ = 0.f;
|
||||||
float x668_;
|
float x668_aimVerticalSpeed;
|
||||||
float x66c_;
|
float x66c_aimHorizontalSpeed;
|
||||||
TUniqueId x670_ = kInvalidUniqueId;
|
TUniqueId x670_ = kInvalidUniqueId;
|
||||||
u32 x674_ = 0;
|
u32 x674_ = 0;
|
||||||
CGunMorph x678_morph;
|
CGunMorph x678_morph;
|
||||||
|
@ -156,7 +157,7 @@ private:
|
||||||
u32 x6c0_ = 0;
|
u32 x6c0_ = 0;
|
||||||
u32 x6c4_ = 0;
|
u32 x6c4_ = 0;
|
||||||
zeus::CAABox x6c8_;
|
zeus::CAABox x6c8_;
|
||||||
CModelData x6e0_;
|
CModelData x6e0_rightHandModel;
|
||||||
CGunWeapon* x72c_currentBeam = nullptr;
|
CGunWeapon* x72c_currentBeam = nullptr;
|
||||||
u32 x730_ = 0;
|
u32 x730_ = 0;
|
||||||
u32 x734_ = 0;
|
u32 x734_ = 0;
|
||||||
|
@ -164,6 +165,7 @@ private:
|
||||||
std::unique_ptr<CGunMotion> x73c_gunMotion;
|
std::unique_ptr<CGunMotion> x73c_gunMotion;
|
||||||
std::unique_ptr<CGrappleArm> x740_grappleArm;
|
std::unique_ptr<CGrappleArm> x740_grappleArm;
|
||||||
std::unique_ptr<CAuxWeapon> x744_auxWeapon;
|
std::unique_ptr<CAuxWeapon> x744_auxWeapon;
|
||||||
|
std::unique_ptr<CModelPointSelector> x748_modelPointSelector;
|
||||||
std::unique_ptr<CPowerBeam> x74c_powerBeam;
|
std::unique_ptr<CPowerBeam> x74c_powerBeam;
|
||||||
std::unique_ptr<CIceBeam> x750_iceBeam;
|
std::unique_ptr<CIceBeam> x750_iceBeam;
|
||||||
std::unique_ptr<CWaveBeam> x754_waveBeam;
|
std::unique_ptr<CWaveBeam> x754_waveBeam;
|
||||||
|
|
|
@ -63,10 +63,12 @@ protected:
|
||||||
bool xe5_26_muted : 1;
|
bool xe5_26_muted : 1;
|
||||||
bool xe5_27_useInSortedLists : 1;
|
bool xe5_27_useInSortedLists : 1;
|
||||||
bool xe5_28_callTouch : 1;
|
bool xe5_28_callTouch : 1;
|
||||||
|
bool xe5_31_ : 1;
|
||||||
u8 xe6_24_fluidCounter : 3;
|
u8 xe6_24_fluidCounter : 3;
|
||||||
u8 xe6_27_renderVisorFlags : 3; // 2: thermal cold, 4: thermal hot
|
u8 xe6_27_renderVisorFlags : 3; // 2: thermal cold, 4: thermal hot
|
||||||
bool xe6_30_enablePitchBend : 1;
|
bool xe6_30_enablePitchBend : 1;
|
||||||
u8 xe6_31_targetableVisorFlags : 4;
|
u8 xe6_31_targetableVisorFlags : 4;
|
||||||
|
bool xe7_27_ : 1;
|
||||||
bool xe7_29_ : 1;
|
bool xe7_29_ : 1;
|
||||||
bool xe7_30_doTargetDistanceTest : 1;
|
bool xe7_30_doTargetDistanceTest : 1;
|
||||||
bool xe7_31_targetable : 1;
|
bool xe7_31_targetable : 1;
|
||||||
|
|
|
@ -19,15 +19,15 @@ CActorModelParticles::CItem::CItem(const CEntity& ent, CActorModelParticles& par
|
||||||
x8_.resize(8);
|
x8_.resize(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetNextBestPt(s32 start, const zeus::CVector3f* vecPtr, s32 vecCount, CRandom16& rnd)
|
u32 GetNextBestPt(s32 start, const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn, CRandom16& rnd)
|
||||||
{
|
{
|
||||||
const zeus::CVector3f& startVec = vecPtr[start];
|
const zeus::CVector3f& startVec = vn[start].first;
|
||||||
u32 ret;
|
u32 ret;
|
||||||
float lastMag = 0.f;
|
float lastMag = 0.f;
|
||||||
for (s32 i = 0; i < 10; ++i)
|
for (s32 i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
u32 idx = u32(rnd.Range(0, vecCount - 1));
|
u32 idx = u32(rnd.Range(0, s32(vn.size()) - 1));
|
||||||
const zeus::CVector3f& rndVec = vecPtr[idx];
|
const zeus::CVector3f& rndVec = vn[idx].first;
|
||||||
float mag = (startVec - rndVec).magSquared();
|
float mag = (startVec - rndVec).magSquared();
|
||||||
if (mag > lastMag)
|
if (mag > lastMag)
|
||||||
{
|
{
|
||||||
|
@ -37,14 +37,14 @@ u32 GetNextBestPt(s32 start, const zeus::CVector3f* vecPtr, s32 vecCount, CRando
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
void CActorModelParticles::CItem::GeneratePoints(const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1)
|
void CActorModelParticles::CItem::GeneratePoints(const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn)
|
||||||
{
|
{
|
||||||
for (std::pair<std::unique_ptr<CElementGen>, u32>& pair: x8_)
|
for (std::pair<std::unique_ptr<CElementGen>, u32>& pair: x8_)
|
||||||
{
|
{
|
||||||
if (pair.first)
|
if (pair.first)
|
||||||
{
|
{
|
||||||
CRandom16 rnd(pair.second);
|
CRandom16 rnd(pair.second);
|
||||||
zeus::CVector3f vec = v1[u32(rnd.Float() * (w1 - 1))];
|
const zeus::CVector3f& vec = vn[u32(rnd.Float() * (vn.size() - 1))].first;
|
||||||
pair.first->SetTranslation(xec_ * vec);
|
pair.first->SetTranslation(xec_ * vec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,9 @@ void CActorModelParticles::CItem::GeneratePoints(const zeus::CVector3f* v1, cons
|
||||||
u32 idx = x80_;
|
u32 idx = x80_;
|
||||||
for (u32 i = 0; i < count; ++i)
|
for (u32 i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
idx = GetNextBestPt(idx, v1, w1, rnd);
|
idx = GetNextBestPt(idx, vn, rnd);
|
||||||
x78_->SetTranslation(xec_ * v1[idx]);
|
x78_->SetTranslation(xec_ * vn[idx].first);
|
||||||
zeus::CVector3f v = v2[idx];
|
zeus::CVector3f v = vn[idx].second;
|
||||||
if (v.canBeNormalized())
|
if (v.canBeNormalized())
|
||||||
{
|
{
|
||||||
v.normalize();
|
v.normalize();
|
||||||
|
@ -79,10 +79,10 @@ void CActorModelParticles::CItem::GeneratePoints(const zeus::CVector3f* v1, cons
|
||||||
std::unique_ptr<CElementGen> iceGen = x128_parent.MakeIceGen();
|
std::unique_ptr<CElementGen> iceGen = x128_parent.MakeIceGen();
|
||||||
iceGen->SetGlobalOrientAndTrans(xf8_);
|
iceGen->SetGlobalOrientAndTrans(xf8_);
|
||||||
|
|
||||||
u32 next = GetNextBestPt(xb0_, v1, w1, rnd);
|
u32 next = GetNextBestPt(xb0_, vn, rnd);
|
||||||
iceGen->SetTranslation(xec_ * v1[next]);
|
iceGen->SetTranslation(xec_ * vn[next].first);
|
||||||
|
|
||||||
iceGen->SetOrientation(zeus::CTransform::MakeRotationsBasedOnY(zeus::CUnitVector3f(v2[next])));
|
iceGen->SetOrientation(zeus::CTransform::MakeRotationsBasedOnY(zeus::CUnitVector3f(vn[next].second)));
|
||||||
|
|
||||||
x8c_.push_back(std::move(iceGen));
|
x8c_.push_back(std::move(iceGen));
|
||||||
xb0_ = (x8c_.size() == 4 ? -1 : next);
|
xb0_ = (x8c_.size() == 4 ? -1 : next);
|
||||||
|
@ -99,9 +99,9 @@ void CActorModelParticles::CItem::GeneratePoints(const zeus::CVector3f* v1, cons
|
||||||
u32 lastRnd;
|
u32 lastRnd;
|
||||||
for (u32 i = 0; i < end; ++i)
|
for (u32 i = 0; i < end; ++i)
|
||||||
{
|
{
|
||||||
xc0_particleElectric->SetOverrideIPos(v1[u32(rnd.Range(0, w1 - 1))] * xec_);
|
xc0_particleElectric->SetOverrideIPos(vn[u32(rnd.Range(0, s32(vn.size()) - 1))].first * xec_);
|
||||||
lastRnd = u32(rnd.Range(0, w1 - 1));
|
lastRnd = u32(rnd.Range(0, s32(vn.size()) - 1));
|
||||||
xc0_particleElectric->SetOverrideFPos(v1[lastRnd] * xec_);
|
xc0_particleElectric->SetOverrideFPos(vn[lastRnd].first * xec_);
|
||||||
xc0_particleElectric->ForceParticleCreation(1);
|
xc0_particleElectric->ForceParticleCreation(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,10 +261,10 @@ void CActorModelParticles::Update(float dt, CStateManager& mgr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CActorModelParticles::PointGenerator(void* item, const zeus::CVector3f* v1,
|
void CActorModelParticles::PointGenerator(void* ctx,
|
||||||
const zeus::CVector3f* v2, int w1)
|
const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn)
|
||||||
{
|
{
|
||||||
reinterpret_cast<CItem*>(item)->GeneratePoints(v1, v2, w1);
|
reinterpret_cast<CItem*>(ctx)->GeneratePoints(vn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CActorModelParticles::SetupHook(TUniqueId uid)
|
void CActorModelParticles::SetupHook(TUniqueId uid)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "zeus/CTransform.hpp"
|
#include "zeus/CTransform.hpp"
|
||||||
#include "Particle/CParticleElectric.hpp"
|
#include "Particle/CParticleElectric.hpp"
|
||||||
#include "Particle/CParticleSwoosh.hpp"
|
#include "Particle/CParticleSwoosh.hpp"
|
||||||
|
#include "Graphics/CModelPointSelector.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -41,7 +42,7 @@ public:
|
||||||
u32 xc8_ = 0;
|
u32 xc8_ = 0;
|
||||||
u32 xcc_seed3 = 99;
|
u32 xcc_seed3 = 99;
|
||||||
zeus::CColor xd0_;
|
zeus::CColor xd0_;
|
||||||
std::unique_ptr<u32> xd4_;
|
std::unique_ptr<CModelPointSelector> xd4_pointSelector;
|
||||||
TToken<CTexture> xdc_ashy;
|
TToken<CTexture> xdc_ashy;
|
||||||
std::unique_ptr<CElementGen> xe4_;
|
std::unique_ptr<CElementGen> xe4_;
|
||||||
zeus::CVector3f xec_ = zeus::CVector3f::skOne;
|
zeus::CVector3f xec_ = zeus::CVector3f::skOne;
|
||||||
|
@ -60,7 +61,7 @@ public:
|
||||||
u8 x134_bits = 0;
|
u8 x134_bits = 0;
|
||||||
public:
|
public:
|
||||||
CItem(const CEntity& ent, CActorModelParticles& parent);
|
CItem(const CEntity& ent, CActorModelParticles& parent);
|
||||||
void GeneratePoints(const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1);
|
void GeneratePoints(const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn);
|
||||||
void Update(float, CStateManager&);
|
void Update(float, CStateManager&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CActorModelParticles();
|
CActorModelParticles();
|
||||||
static void PointGenerator(void* item, const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1);
|
static void PointGenerator(void* item, const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn);
|
||||||
void AddStragglersToRenderer(const CStateManager& mgr);
|
void AddStragglersToRenderer(const CStateManager& mgr);
|
||||||
void Update(float dt, CStateManager& mgr);
|
void Update(float dt, CStateManager& mgr);
|
||||||
void SetupHook(TUniqueId uid);
|
void SetupHook(TUniqueId uid);
|
||||||
|
|
|
@ -1007,7 +1007,7 @@ void CGameArea::FillInStaticGeometry()
|
||||||
TToken<CModel> nullModel;
|
TToken<CModel> nullModel;
|
||||||
inst.m_instance = std::make_unique<CBooModel>
|
inst.m_instance = std::make_unique<CBooModel>
|
||||||
(nullModel, &inst.m_surfaces, x12c_postConstructed->m_materialSet, vtxFmt, vbo, ibo,
|
(nullModel, &inst.m_surfaces, x12c_postConstructed->m_materialSet, vtxFmt, vbo, ibo,
|
||||||
hmdlMeta.weightCount, hmdlMeta.bankCount, inst.x34_aabb, inst.x0_visorFlags, 1, nullptr);
|
inst.x34_aabb, inst.x0_visorFlags, 1, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit f63a6a704b1e2ce3534e4d83cb2d2efd78b4966d
|
Subproject commit 77e859a8176e58efadd8d49e2ee58f0a2b831dd0
|
Loading…
Reference in New Issue