mirror of
https://github.com/PrimeDecomp/prime.git
synced 2026-07-12 18:18:56 -07:00
DolphinCSkinnedModel 99% & CSkinnedModelWithAvgNormals 96% (#51)
This commit is contained in:
@@ -14820,21 +14820,21 @@ Initialize__14CGameAllocatorFR10COsContext = .text:0x803521BC; // type:function
|
||||
__dt__14CGameAllocatorFv = .text:0x80352544; // type:function size:0x88 scope:global
|
||||
__ct__14CGameAllocatorFv = .text:0x803525CC; // type:function size:0x94 scope:global
|
||||
GetMemInfoFromBlockPtr__14CGameAllocatorCFPCv = .text:0x80352660; // type:function size:0x8 scope:global
|
||||
fn_80352668 = .text:0x80352668; // type:function size:0xA0
|
||||
AllocateNewWorkspace__13CSkinnedModelFPPf = .text:0x80352668; // type:function size:0xA0 scope:global
|
||||
ClearPointGeneratorFunc__13CSkinnedModelFv = .text:0x80352708; // type:function size:0xC scope:global
|
||||
SetPointGeneratorFunc__13CSkinnedModelFPvPFPvPC9CVector3fPC9CVector3fi_v = .text:0x80352714; // type:function size:0xC scope:global
|
||||
RemoveDummySkinnedModelRef__13CSkinnedModelFv = .text:0x80352720; // type:function size:0x20
|
||||
fn_80352740 = .text:0x80352740; // type:function size:0x20
|
||||
fn_80352760 = .text:0x80352760; // type:function size:0x10C
|
||||
AddDummySkinnedModelRef__13CSkinnedModelFv = .text:0x80352740; // type:function size:0x20
|
||||
PostDrawFunc__13CSkinnedModelCFv = .text:0x80352760; // type:function size:0x10C
|
||||
AllocateStorage__13CSkinnedModelFv = .text:0x8035286C; // type:function size:0x180 scope:global
|
||||
EnsureAllocation__13CSkinnedModelFi = .text:0x803529EC; // type:function size:0x184 scope:global
|
||||
TickAllocations__13CSkinnedModelFv = .text:0x80352B70; // type:function size:0xA8 scope:global
|
||||
CalculateDefault__13CSkinnedModelFv = .text:0x80352C18; // type:function size:0xE0 scope:global
|
||||
Calculate__13CSkinnedModelFRC17CPoseAsTransformsRCQ24rstl37optional_object<18CVertexMorphEffect>PCfPf = .text:0x80352CF8; // type:function size:0x1F0 scope:global
|
||||
fn_80352EE8 = .text:0x80352EE8; // type:function size:0x38
|
||||
DoDrawCallback__13CSkinnedModelF14FCustomDrawCPv = .text:0x80352F20; // type:function size:0x144 scope:global
|
||||
fn_80353064 = .text:0x80353064; // type:function size:0xBC
|
||||
fn_80353120 = .text:0x80353120; // type:function size:0x15C
|
||||
Draw__13CSkinnedModelCFPCfPCfRC11CModelFlags = .text:0x80352EE8; // type:function size:0x38 scope:global
|
||||
DoDrawCallback__13CSkinnedModelFPFPCfPCfPCv_vPv = .text:0x80352F20; // type:function size:0x144 scope:global
|
||||
Draw__13CSkinnedModelCFRC11CModelFlags = .text:0x80353064; // type:function size:0xBC scope:global
|
||||
Construct__13CSkinnedModelFv = .text:0x80353120; // type:function size:0x15C
|
||||
__dt__13CSkinnedModelFv = .text:0x8035327C; // type:function size:0xE8 scope:global
|
||||
__ct__13CSkinnedModelFRC13CSkinnedModel = .text:0x80353364; // type:function size:0xD4 scope:global
|
||||
__ct__13CSkinnedModelFRC21TLockedToken<6CModel>RC26TLockedToken<10CSkinRules>RC31TLockedToken<15CCharLayoutInfo>Q213CSkinnedModel14EDataOwnership = .text:0x80353438; // type:function size:0xD4 scope:global
|
||||
@@ -14848,7 +14848,7 @@ ProcessingNormals__10CSkinRulesFiPPUs = .text:0x803538F4; // type:function size:
|
||||
ProcessingPoints__10CSkinRulesFiPPUs = .text:0x803539F0; // type:function size:0xFC scope:global
|
||||
WaitForQueue__Fv = .text:0x80353AEC; // type:function size:0x30 scope:global
|
||||
StartNextTransaction__10CSkinRulesFv = .text:0x80353B1C; // type:function size:0xF8 scope:global
|
||||
InitLockedCacheState__10CSkinRulesFRC10CSkinRules = .text:0x80353C14; // type:function size:0x50 scope:global
|
||||
InitLockedCacheState__10CSkinRulesFRC6CModel = .text:0x80353C14; // type:function size:0x50 scope:global
|
||||
FSkinRulesFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer = .text:0x80353C64; // type:function size:0xE0 scope:global
|
||||
__dt__20TToken<10CSkinRules>Fv = .text:0x80353D44; // type:function size:0x90 scope:global
|
||||
GetIObjObjectFor__20TToken<10CSkinRules>FRCQ24rstl22auto_ptr<10CSkinRules> = .text:0x80353DD4; // type:function size:0x2C scope:global
|
||||
@@ -14936,17 +14936,17 @@ Reset__18CVertexMorphEffectFRC13CUnitVector3fRC9CVector3ff = .text:0x803574E0; /
|
||||
MorphVertices__18CVertexMorphEffectCFP9CVector3fPC9CVector3fRC26TLockedToken<10CSkinRules>RC17CPoseAsTransformsUi = .text:0x80357598; // type:function size:0x3D4 scope:global
|
||||
Update__18CVertexMorphEffectFf = .text:0x8035796C; // type:function size:0x38 scope:global
|
||||
__ct__27CSkinnedModelWithAvgNormalsFRC13CSkinnedModel = .text:0x803579A4; // type:function size:0x35C scope:global
|
||||
fn_80357D00 = .text:0x80357D00; // type:function size:0x7C
|
||||
fn_80357D7C = .text:0x80357D7C; // type:function size:0x28
|
||||
fn_80357DA4 = .text:0x80357DA4; // type:function size:0x54
|
||||
fn_80357DF8 = .text:0x80357DF8; // type:function size:0x98
|
||||
fn_80357E90 = .text:0x80357E90; // type:function size:0xB4
|
||||
fn_80357F44 = .text:0x80357F44; // type:function size:0x8C
|
||||
fn_80357FD0 = .text:0x80357FD0; // type:function size:0x50
|
||||
fn_80358020 = .text:0x80358020; // type:function size:0x7C
|
||||
fn_8035809C = .text:0x8035809C; // type:function size:0x78
|
||||
push_back__Q24rstl105vector<Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>,Q24rstl17rmemory_allocator>FRCQ24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>> = .text:0x80357D00; // type:function size:0x7C scope:weak
|
||||
construct<Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>>__4rstlFPvRCQ24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>> = .text:0x80357D7C; // type:function size:0x28
|
||||
__ct__Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>FRCQ24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>> = .text:0x80357DA4; // type:function size:0x54 scope:weak
|
||||
__ct__Q24rstl35list<Ui,Q24rstl17rmemory_allocator>FRCQ24rstl35list<Ui,Q24rstl17rmemory_allocator> = .text:0x80357DF8; // type:function size:0x98 scope:weak
|
||||
insert<Q34rstl35list<Ui,Q24rstl17rmemory_allocator>14const_iterator>__Q24rstl35list<Ui,Q24rstl17rmemory_allocator>FRCQ34rstl35list<Ui,Q24rstl17rmemory_allocator>8iteratorQ34rstl35list<Ui,Q24rstl17rmemory_allocator>14const_iteratorQ34rstl35list<Ui,Q24rstl17rmemory_allocator>14const_iterator = .text:0x80357E90; // type:function size:0xB4
|
||||
__dt__Q34rstl35list<Ui,Q24rstl17rmemory_allocator>14destroy_helperFv = .text:0x80357F44; // type:function size:0x8C scope:weak
|
||||
__ct__Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>FRC9CVector3fRCQ24rstl35list<Ui,Q24rstl17rmemory_allocator> = .text:0x80357FD0; // type:function size:0x50 scope:weak
|
||||
do_erase__Q24rstl35list<Ui,Q24rstl17rmemory_allocator>FPQ34rstl35list<Ui,Q24rstl17rmemory_allocator>4node = .text:0x80358020; // type:function size:0x7C scope:weak
|
||||
__dt__Q24rstl35list<Ui,Q24rstl17rmemory_allocator>Fv = .text:0x8035809C; // type:function size:0x78 scope:weak
|
||||
reserve__Q24rstl105vector<Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>,Q24rstl17rmemory_allocator>Fi = .text:0x80358114; // type:function size:0xE0 scope:global
|
||||
fn_803581F4 = .text:0x803581F4; // type:function size:0x68
|
||||
uninitialized_copy<Q24rstl231pointer_iterator<Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>,Q24rstl105vector<Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>,PQ24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>>__4rstlFQ24rstl231pointer_iterator<Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>,Q24rstl105vector<Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>Q24rstl231pointer_iterator<Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>,Q24rstl105vector<Q24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>PQ24rstl61pair<9CVector3f,Q24rstl35list<Ui,Q24rstl17rmemory_allocator>> = .text:0x803581F4; // type:function size:0x68
|
||||
__dt__13CTimeProviderFv = .text:0x8035825C; // type:function size:0x78 scope:global
|
||||
__ct__13CTimeProviderFRCf = .text:0x803582D4; // type:function size:0x60 scope:global
|
||||
GetMRAMSafe__10CARAMTokenFv = .text:0x80358334; // type:function size:0x54 scope:global
|
||||
@@ -17838,7 +17838,7 @@ lbl_803D8220 = .rodata:0x803D8220; // type:object size:0x7 data:string
|
||||
@stringBase0 = .rodata:0x803D8230; // type:object size:0xD scope:local data:string_table
|
||||
lbl_803D8240 = .rodata:0x803D8240; // type:object size:0x7 data:string
|
||||
lbl_803D8248 = .rodata:0x803D8248; // type:object size:0xB0
|
||||
lbl_803D82F8 = .rodata:0x803D82F8; // type:object size:0x7 data:string
|
||||
@stringBase0 = .rodata:0x803D82F8; // type:object size:0x7 scope:local data:string_table
|
||||
lbl_803D8300 = .rodata:0x803D8300; // type:object size:0x7 data:string
|
||||
lbl_803D8308 = .rodata:0x803D8308; // type:object size:0x7 data:string
|
||||
skInvalidString = .rodata:0x803D8310; // type:object size:0x10 scope:local data:wstring
|
||||
@@ -22173,12 +22173,12 @@ lbl_805A95E4 = .sbss:0x805A95E4; // type:object size:0x4 data:4byte
|
||||
lbl_805A95E8 = .sbss:0x805A95E8; // type:object size:0x1 data:byte
|
||||
lbl_805A95E9 = .sbss:0x805A95E9; // type:object size:0x1 data:byte
|
||||
lbl_805A95EA = .sbss:0x805A95EA; // type:object size:0x6 data:byte
|
||||
lbl_805A95F0 = .sbss:0x805A95F0; // type:object size:0x4 data:4byte
|
||||
lbl_805A95F4 = .sbss:0x805A95F4; // type:object size:0x4 data:4byte
|
||||
sPointGen__13CSkinnedModel = .sbss:0x805A95F0; // type:object size:0x4 scope:global data:4byte
|
||||
sPointGenData__13CSkinnedModel = .sbss:0x805A95F4; // type:object size:0x4 scope:global data:4byte
|
||||
skCurrentToken__8Skinning = .sbss:0x805A95F8; // type:object size:0x2 data:2byte
|
||||
sNumSkinnedObjects__8Skinning = .sbss:0x805A95FC; // type:object size:0x4 data:4byte
|
||||
sSkinningInitialized__8Skinning = .sbss:0x805A9600; // type:object size:0x1 data:byte
|
||||
lbl_805A9601 = .sbss:0x805A9601; // type:object size:0x7 data:byte
|
||||
sbDumpedSpinLockMessage__8Skinning = .sbss:0x805A9601; // type:object size:0x1 scope:local data:byte
|
||||
lbl_805A9608 = .sbss:0x805A9608; // type:object size:0x1 data:byte
|
||||
lbl_805A960C = .sbss:0x805A960C; // type:object size:0x1 data:byte
|
||||
lbl_805A9610 = .sbss:0x805A9610; // type:object size:0x4 data:4byte
|
||||
|
||||
@@ -3,14 +3,26 @@
|
||||
|
||||
#include "Kyoto/Animation/CVirtualBone.hpp"
|
||||
|
||||
class CCharLayoutInfo;
|
||||
class CInputStream;
|
||||
class CModel;
|
||||
class CPoseAsTransforms;
|
||||
|
||||
class CSkinRules {
|
||||
public:
|
||||
CSkinRules(CInputStream& in);
|
||||
~CSkinRules();
|
||||
|
||||
void InitLockedCacheState(const CModel& model);
|
||||
void BuildAccumulatedTransforms(const CPoseAsTransforms& pose,
|
||||
const CCharLayoutInfo& layoutInfo) const;
|
||||
void BuildPoints(volatile void* pipe) const;
|
||||
void BuildNormals(volatile void* pipe) const;
|
||||
void BuildNormalsFrom(const CVector3f* averageNormals, CVector3f* out) const;
|
||||
uint GetNumPoints() const { return x10_vertexCount; }
|
||||
uint GetNumNormals() const { return x14_normalCount; }
|
||||
int GetNumVirtualBones() const { return x0_virtualBones.size(); }
|
||||
const rstl::vector< CVirtualBone >& GetVirtualBones() const { return x0_virtualBones; }
|
||||
|
||||
private:
|
||||
rstl::vector< CVirtualBone > x0_virtualBones;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include "Kyoto/Animation/CSkinRules.hpp"
|
||||
#include "Kyoto/TToken.hpp"
|
||||
|
||||
#include "rstl/auto_ptr.hpp"
|
||||
@@ -10,12 +11,13 @@
|
||||
|
||||
class CModel;
|
||||
class CModelFlags;
|
||||
class CSkinRules;
|
||||
class CCharLayoutInfo;
|
||||
class CPoseAsTransforms;
|
||||
class CVector3f;
|
||||
class CVertexMorphEffect;
|
||||
|
||||
typedef void (*TDrawFunc)(const float*, const float*, const void*);
|
||||
|
||||
class CSkinnedModel {
|
||||
public:
|
||||
enum EDataOwnership {
|
||||
@@ -33,34 +35,49 @@ public:
|
||||
const TLockedToken< CCharLayoutInfo >& GetLayoutInfo() const { return x1c_layoutInfo; }
|
||||
|
||||
void CalculateDefault();
|
||||
int GetNumPoints() const;
|
||||
int GetNumPoints() const { return x10_skinRules->GetNumPoints(); }
|
||||
const CVector3f* GetPositions() const;
|
||||
void Calculate(const CPoseAsTransforms&, const rstl::optional_object< CVertexMorphEffect >&,
|
||||
const float*, float*);
|
||||
void Draw(const CModelFlags&) const;
|
||||
void Draw(const float* positions, const float* normals, const CModelFlags& flags) const;
|
||||
void DoDrawCallback(TDrawFunc func, void* data);
|
||||
void PostDrawFunc() const;
|
||||
|
||||
float* AllocateNewWorkspace(float** vertOut);
|
||||
|
||||
static void SetPointGeneratorFunc(void*, void (*)(void*, const CVector3f*, const CVector3f*, int));
|
||||
static void ClearPointGeneratorFunc();
|
||||
static void AddDummySkinnedModelRef();
|
||||
static void RemoveDummySkinnedModelRef();
|
||||
|
||||
void Construct();
|
||||
void AllocateStorage();
|
||||
static void TickAllocations();
|
||||
static void* EnsureAllocation(int size);
|
||||
|
||||
typedef void (*TPointGenFunc)(void*, const CVector3f*, const CVector3f*, int);
|
||||
static TPointGenFunc sPointGen;
|
||||
static void* sPointGenData;
|
||||
|
||||
private:
|
||||
TLockedToken< CModel > x4_model;
|
||||
TLockedToken< CSkinRules > x10_skinRules;
|
||||
TLockedToken< CCharLayoutInfo > x1c_layoutInfo;
|
||||
rstl::auto_ptr< float[] > x28_vertWorkspace;
|
||||
rstl::auto_ptr< float[] > x30_normalWorkspace;
|
||||
mutable rstl::auto_ptr< float > x28_vertWorkspace;
|
||||
mutable rstl::auto_ptr< float > x30_normalWorkspace;
|
||||
bool x38_owned;
|
||||
bool x39_disableWorkspaces;
|
||||
};
|
||||
|
||||
class CSkinnedModelWithAvgNormals {
|
||||
CSkinnedModel x0_skinnedModel;
|
||||
uchar x3c_pad[4];
|
||||
const float* x40_avgNormals;
|
||||
rstl::auto_ptr< float > x3c_avgNormals;
|
||||
|
||||
public:
|
||||
CSkinnedModelWithAvgNormals(const CSkinnedModel& model);
|
||||
const CSkinnedModel& GetSkinnedModel() const { return x0_skinnedModel; }
|
||||
const float* GetAvgNormals() const { return x40_avgNormals; }
|
||||
float* GetAvgNormals() const { return x3c_avgNormals.get(); }
|
||||
};
|
||||
|
||||
#endif // _CSKINNEDMODEL
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
explicit CVirtualBone(CInputStream& in);
|
||||
const rstl::reserved_vector< SSkinWeighting, 3 >& GetWeights() const { return x0_weights; }
|
||||
uint GetVertexCount() const { return x1c_vertexCount; }
|
||||
const CTransform4f& GetTransform() const { return x20_xf; }
|
||||
|
||||
void BuildPoints(const ushort*, volatile void*, int) const;
|
||||
void BuildNormals(const ushort*, volatile void*, int) const;
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
CModel(const rstl::auto_ptr< uchar >& data, int length, IObjectStore& store);
|
||||
void Touch(int) const;
|
||||
void Draw(const CModelFlags&) const;
|
||||
void Draw(const float* positions, const float* normals, const CModelFlags& flags) const;
|
||||
bool IsLoaded(int matIdx) const;
|
||||
const float* GetPositions() const;
|
||||
const float* GetNormals() const;
|
||||
|
||||
@@ -29,6 +29,8 @@ void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWaterMark, u32 loWaterMark);
|
||||
GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb);
|
||||
void GXEnableBreakPt(void* breakPt);
|
||||
void GXDisableBreakPt(void);
|
||||
volatile void* GXRedirectWriteGatherPipe(void* buf);
|
||||
void GXRestoreWriteGatherPipe(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef _RSTL_ALLOCATOR_AUTO_PTR
|
||||
#define _RSTL_ALLOCATOR_AUTO_PTR
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace rstl {
|
||||
template < typename T, typename Alloc >
|
||||
struct allocator_auto_ptr {
|
||||
allocator_auto_ptr(T* ptr, Alloc* alloc) : x0_ptr(ptr), x4_alloc(alloc) {}
|
||||
~allocator_auto_ptr() {
|
||||
if (x0_ptr != nullptr) {
|
||||
x4_alloc->deallocate(x0_ptr);
|
||||
x0_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
T* release() const {
|
||||
T* ret = x0_ptr;
|
||||
const_cast< allocator_auto_ptr* >(this)->x0_ptr = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
T* x0_ptr;
|
||||
Alloc* x4_alloc;
|
||||
};
|
||||
} // namespace rstl
|
||||
|
||||
#endif // _RSTL_ALLOCATOR_AUTO_PTR
|
||||
+57
-3
@@ -12,7 +12,6 @@ class list {
|
||||
public:
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
iterator erase(const iterator& item) { return do_erase(item.get_node()); }
|
||||
|
||||
// private:
|
||||
#pragma pack(push, 1)
|
||||
@@ -26,6 +25,33 @@ public:
|
||||
, xc_empty_prev(reinterpret_cast< node* >(&xc_empty_prev))
|
||||
, x10_empty_next(reinterpret_cast< node* >(&xc_empty_prev))
|
||||
, x14_count(0) {}
|
||||
|
||||
struct destroy_helper {
|
||||
destroy_helper(list* l) : x0_list(l), x4_active(true) {}
|
||||
~destroy_helper() {
|
||||
if (x4_active) {
|
||||
x0_list->destroy();
|
||||
}
|
||||
}
|
||||
void release() { x4_active = false; }
|
||||
|
||||
private:
|
||||
list* x0_list;
|
||||
bool x4_active;
|
||||
};
|
||||
|
||||
list(const list& other)
|
||||
: x0_allocator(other.x0_allocator)
|
||||
, x4_start(reinterpret_cast< node* >(&xc_empty_prev))
|
||||
, x8_end(reinterpret_cast< node* >(&xc_empty_prev))
|
||||
, xc_empty_prev(reinterpret_cast< node* >(&xc_empty_prev))
|
||||
, x10_empty_next(reinterpret_cast< node* >(&xc_empty_prev))
|
||||
, x14_count(0) {
|
||||
destroy_helper dh(this);
|
||||
insert(end(), other.begin(), other.end());
|
||||
dh.release();
|
||||
}
|
||||
|
||||
~list();
|
||||
node* do_erase(node* item);
|
||||
|
||||
@@ -36,6 +62,9 @@ public:
|
||||
int size() const { return x14_count; }
|
||||
bool empty() const { return x14_count == 0; }
|
||||
|
||||
T& front() { return *x4_start->get_value(); }
|
||||
const T& front() const { return *x4_start->get_value(); }
|
||||
|
||||
void pop_front() { erase(x4_start); }
|
||||
|
||||
iterator begin() { return iterator(x4_start); }
|
||||
@@ -43,6 +72,7 @@ public:
|
||||
iterator end() { return iterator(x8_end); }
|
||||
const_iterator end() const { return const_iterator(x8_end); }
|
||||
|
||||
iterator erase(const iterator& item) { return do_erase(item.get_node()); }
|
||||
iterator erase(const iterator& start, const iterator& end) {
|
||||
node* last = end.get_node();
|
||||
node* it = start.get_node();
|
||||
@@ -90,6 +120,30 @@ public:
|
||||
return nn;
|
||||
}
|
||||
|
||||
iterator insert(const iterator& pos, const T& val) {
|
||||
do_insert_before(pos.get_node(), val);
|
||||
return pos;
|
||||
}
|
||||
|
||||
template < typename InputIterator >
|
||||
void insert(const iterator& pos, InputIterator first, InputIterator last) {
|
||||
node* cur = first.get_node();
|
||||
while (cur != last.get_node()) {
|
||||
do_insert_before(pos.get_node(), *cur->get_value());
|
||||
cur = cur->get_next();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: demo map shows this delegates to clear(),
|
||||
// but this matches better in CSkinnedModelWithAvgNormals
|
||||
void destroy() {
|
||||
node* end = x8_end;
|
||||
node* it = x4_start;
|
||||
while (it != end) {
|
||||
it = do_erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void remove(const T& val);
|
||||
|
||||
// TODO non-matching
|
||||
@@ -184,7 +238,7 @@ list< T, Alloc >::~list() {
|
||||
node* it = cur;
|
||||
node* next = cur->get_next();
|
||||
cur = next;
|
||||
destroy(it->get_value());
|
||||
rstl::destroy(it->get_value());
|
||||
x0_allocator.deallocate(it);
|
||||
}
|
||||
}
|
||||
@@ -197,7 +251,7 @@ typename list< T, Alloc >::node* list< T, Alloc >::do_erase(node* node) {
|
||||
}
|
||||
node->get_prev()->set_next(node->get_next());
|
||||
node->get_next()->set_prev(node->get_prev());
|
||||
destroy(node->get_value());
|
||||
rstl::destroy(node->get_value());
|
||||
x0_allocator.deallocate(node);
|
||||
x14_count--;
|
||||
return result;
|
||||
|
||||
+1
-20
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include "rstl/allocator_auto_ptr.hpp"
|
||||
#include "rstl/iterator.hpp"
|
||||
#include "rstl/pointer_iterator.hpp"
|
||||
#include "rstl/rmemory_allocator.hpp"
|
||||
@@ -10,26 +11,6 @@
|
||||
class CInputStream;
|
||||
|
||||
namespace rstl {
|
||||
template < typename T, typename Alloc >
|
||||
struct allocator_auto_ptr {
|
||||
allocator_auto_ptr(T* ptr, Alloc* alloc) : x0_ptr(ptr), x4_alloc(alloc) {}
|
||||
~allocator_auto_ptr() {
|
||||
if (x0_ptr != nullptr) {
|
||||
x4_alloc->deallocate(x0_ptr);
|
||||
x0_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
T* release() const {
|
||||
T* ret = x0_ptr;
|
||||
const_cast< allocator_auto_ptr* >(this)->x0_ptr = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
T* x0_ptr;
|
||||
Alloc* x4_alloc;
|
||||
};
|
||||
|
||||
template < typename T, typename Alloc = rmemory_allocator >
|
||||
class vector {
|
||||
|
||||
@@ -86,7 +86,6 @@ uint CMediumAllocPool::GetNumBlocksAvailable() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma inline_max_size(250)
|
||||
void CMediumAllocPool::AddPuddle(uint len, void* data, const bool unk) {
|
||||
x0_list.push_back(SMediumAllocPuddle(len, data, unk));
|
||||
x18_lastNodePrev = x0_list.end();
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "Kyoto/Animation/CSkinnedModel.hpp"
|
||||
|
||||
#include "Kyoto/Alloc/CMemory.hpp"
|
||||
#include "Kyoto/Graphics/CModel.hpp"
|
||||
#include "Kyoto/Math/CVector3f.hpp"
|
||||
|
||||
#include "rstl/list.hpp"
|
||||
#include "rstl/pair.hpp"
|
||||
#include "rstl/vector.hpp"
|
||||
|
||||
#pragma inline_max_size(250)
|
||||
|
||||
typedef rstl::pair< CVector3f, rstl::list< uint > > TPosToVertListPair;
|
||||
|
||||
CSkinnedModelWithAvgNormals::CSkinnedModelWithAvgNormals(const CSkinnedModel& skinnedModel)
|
||||
: x0_skinnedModel(skinnedModel), x3c_avgNormals(rs_new float[skinnedModel.GetNumPoints() * 12]) {
|
||||
int vertexCount = skinnedModel.GetNumPoints();
|
||||
const CVector3f* modelPositions =
|
||||
reinterpret_cast< const CVector3f* >(skinnedModel.GetModel()->GetPositions());
|
||||
|
||||
rstl::vector< TPosToVertListPair > vertMap;
|
||||
vertMap.reserve(vertexCount);
|
||||
|
||||
for (uint vertIdx = 0; vertIdx < vertexCount; ++vertIdx) {
|
||||
bool foundEqPos = false;
|
||||
uint vopolSize = vertMap.size();
|
||||
for (uint i = 0; i < vopolSize; ++i) {
|
||||
if (vertMap[i].first.IsEqu(modelPositions[vertIdx])) {
|
||||
foundEqPos = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundEqPos) {
|
||||
rstl::list< uint > tmpList;
|
||||
for (uint j = vertIdx; j < vertexCount; ++j) {
|
||||
if (modelPositions[j] == modelPositions[vertIdx]) {
|
||||
tmpList.push_back(j);
|
||||
}
|
||||
}
|
||||
vertMap.push_back(TPosToVertListPair(modelPositions[vertIdx], tmpList));
|
||||
}
|
||||
}
|
||||
|
||||
const CVector3f* normals =
|
||||
reinterpret_cast< const CVector3f* >(skinnedModel.GetModel()->GetNormals());
|
||||
float* avgNormals = x3c_avgNormals.get();
|
||||
|
||||
TPosToVertListPair* mapCur = vertMap.xc_items;
|
||||
TPosToVertListPair* mapEnd = mapCur + vertMap.x4_count;
|
||||
while (mapCur != mapEnd) {
|
||||
CVector3f accum(0.f, 0.f, 0.f);
|
||||
|
||||
AUTO(lit, mapCur->second.begin());
|
||||
AUTO(listEnd, mapCur->second.end());
|
||||
for (; lit != listEnd; ++lit) {
|
||||
accum += normals[*lit];
|
||||
}
|
||||
|
||||
lit = mapCur->second.begin();
|
||||
CVector3f normalized = accum.AsNormalized();
|
||||
for (; lit != listEnd; ++lit) {
|
||||
reinterpret_cast< CVector3f* >(avgNormals)[*lit] = normalized;
|
||||
}
|
||||
++mapCur;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,25 @@
|
||||
#pragma inline_max_size(259) // TODO: adjusted from 250 for Skinning::AddSkinnedRef
|
||||
|
||||
#include "Kyoto/Animation/CSkinnedModel.hpp"
|
||||
|
||||
#include "Kyoto/Alloc/CCircularBuffer.hpp"
|
||||
#include "Kyoto/Alloc/CMemory.hpp"
|
||||
#include "Kyoto/Animation/CSkinRules.hpp"
|
||||
#include "Kyoto/Animation/CVertexMorphEffect.hpp"
|
||||
#include "Kyoto/Graphics/CGraphics.hpp"
|
||||
#include "Kyoto/Graphics/CModel.hpp"
|
||||
#include "Kyoto/Graphics/CModelFlags.hpp"
|
||||
|
||||
#include <dolphin/PPCArch.h>
|
||||
#include <dolphin/gx.h>
|
||||
#include <dolphin/os.h>
|
||||
#include <dolphin/os/OSCache.h>
|
||||
|
||||
#include <rstl/optional_object.hpp>
|
||||
|
||||
CSkinnedModel::TPointGenFunc CSkinnedModel::sPointGen;
|
||||
void* CSkinnedModel::sPointGenData;
|
||||
|
||||
struct SSkinnedAllocation {
|
||||
SSkinnedAllocation(void* ptr, int w1, ushort w2) : x0_ptr(ptr), x4_unk1(w1), x8_unk2(w2) {}
|
||||
|
||||
@@ -20,6 +35,7 @@ static bool sSkinningInitialized = false;
|
||||
static char sStaticSkinningData[0x80000] ATTRIBUTE_ALIGN(32);
|
||||
static rstl::optional_object< CCircularBuffer > sSkinningBuffer;
|
||||
static rstl::list< SSkinnedAllocation > sAllocations;
|
||||
static bool sbDumpedSpinLockMessage = false;
|
||||
|
||||
void AddSkinnedRef();
|
||||
void DelSkinnedRef();
|
||||
@@ -44,6 +60,254 @@ void Skinning::DelSkinnedRef() {
|
||||
--sNumSkinnedObjects;
|
||||
if (sNumSkinnedObjects == 0) {
|
||||
sSkinningBuffer.clear();
|
||||
sAllocations.clear();
|
||||
AUTO(end, sAllocations.end());
|
||||
AUTO(it, sAllocations.begin());
|
||||
while (it != end) {
|
||||
it = sAllocations.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSkinnedModel::CSkinnedModel(const TLockedToken< CModel >& model,
|
||||
const TLockedToken< CSkinRules >& skinRules,
|
||||
const TLockedToken< CCharLayoutInfo >& layoutInfo,
|
||||
EDataOwnership ownership)
|
||||
: x4_model(model)
|
||||
, x10_skinRules(skinRules)
|
||||
, x1c_layoutInfo(layoutInfo)
|
||||
, x28_vertWorkspace()
|
||||
, x30_normalWorkspace()
|
||||
, x38_owned(ownership == kDO_Owned)
|
||||
, x39_disableWorkspaces(false) {
|
||||
Construct();
|
||||
}
|
||||
|
||||
CSkinnedModel::CSkinnedModel(const CSkinnedModel& other)
|
||||
: x4_model(other.x4_model)
|
||||
, x10_skinRules(other.x10_skinRules)
|
||||
, x1c_layoutInfo(other.x1c_layoutInfo)
|
||||
, x28_vertWorkspace()
|
||||
, x30_normalWorkspace()
|
||||
, x38_owned(other.x38_owned)
|
||||
, x39_disableWorkspaces(false) {
|
||||
Construct();
|
||||
}
|
||||
|
||||
CSkinnedModel::~CSkinnedModel() { Skinning::DelSkinnedRef(); }
|
||||
|
||||
void CSkinnedModel::Construct() {
|
||||
Skinning::AddSkinnedRef();
|
||||
if (!x38_owned) {
|
||||
uint numPoints = x10_skinRules->GetNumPoints();
|
||||
uint numNormals = x10_skinRules->GetNumNormals();
|
||||
x28_vertWorkspace = rs_new float[numPoints * 12];
|
||||
x30_normalWorkspace = rs_new float[numNormals * 12];
|
||||
}
|
||||
if (x10_skinRules->GetNumVirtualBones() == 1) {
|
||||
x39_disableWorkspaces = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CSkinnedModel::Draw(const CModelFlags& flags) const {
|
||||
if (x39_disableWorkspaces) {
|
||||
CTransform4f saved(CGraphics::GetModelMatrix());
|
||||
CGraphics::SetModelMatrix(saved * x10_skinRules->GetVirtualBones()[0].GetTransform());
|
||||
x4_model->Draw(flags);
|
||||
CGraphics::SetModelMatrix(saved);
|
||||
} else if (x28_vertWorkspace.null()) {
|
||||
x4_model->Draw(flags);
|
||||
} else {
|
||||
x4_model->Draw(x28_vertWorkspace.get(), x30_normalWorkspace.get(), flags);
|
||||
PostDrawFunc();
|
||||
}
|
||||
}
|
||||
|
||||
void CSkinnedModel::DoDrawCallback(void (*func)(const float*, const float*, const void*),
|
||||
void* data) {
|
||||
const float* normals;
|
||||
if (x39_disableWorkspaces) {
|
||||
CTransform4f saved(CGraphics::GetModelMatrix());
|
||||
CGraphics::SetModelMatrix(saved * x10_skinRules->GetVirtualBones()[0].GetTransform());
|
||||
normals = x4_model->GetNormals();
|
||||
func(x4_model->GetPositions(), normals, data);
|
||||
CGraphics::SetModelMatrix(saved);
|
||||
} else if (x28_vertWorkspace.null()) {
|
||||
normals = x4_model->GetNormals();
|
||||
func(x4_model->GetPositions(), normals, data);
|
||||
} else {
|
||||
func(x28_vertWorkspace.get(), x30_normalWorkspace.get(), data);
|
||||
uint vertSize = (x10_skinRules->GetNumPoints() * 12 + 31) & ~31u;
|
||||
DCFlushRangeNoSync(x28_vertWorkspace.get(), vertSize);
|
||||
uint normSize = (x10_skinRules->GetNumNormals() * 12 + 31) & ~31u;
|
||||
DCFlushRangeNoSync(x30_normalWorkspace.get(), normSize);
|
||||
PPCSync();
|
||||
PostDrawFunc();
|
||||
}
|
||||
}
|
||||
|
||||
void CSkinnedModel::Draw(const float* positions, const float* normals,
|
||||
const CModelFlags& flags) const {
|
||||
x4_model->Draw(positions, normals, flags);
|
||||
PostDrawFunc();
|
||||
}
|
||||
|
||||
void CSkinnedModel::Calculate(const CPoseAsTransforms& pose,
|
||||
const rstl::optional_object< CVertexMorphEffect >& morphEffect,
|
||||
const float* averagedNormals, float* workVerts) {
|
||||
uint vertSize = x10_skinRules->GetNumPoints() * 12;
|
||||
uint normSize = x10_skinRules->GetNumNormals() * 12;
|
||||
float* verts;
|
||||
|
||||
if (workVerts != nullptr) {
|
||||
verts = workVerts;
|
||||
} else {
|
||||
if (x39_disableWorkspaces) {
|
||||
x10_skinRules->BuildAccumulatedTransforms(pose, **x1c_layoutInfo);
|
||||
return;
|
||||
}
|
||||
AllocateStorage();
|
||||
verts = x28_vertWorkspace.get();
|
||||
}
|
||||
|
||||
uint alignedVertSize = (vertSize + 31) & ~31u;
|
||||
uint totalSize = alignedVertSize + ((normSize + 31) & ~31u);
|
||||
|
||||
DCFlushRange(verts, totalSize);
|
||||
BOOL interruptState = OSDisableInterrupts();
|
||||
volatile void* pipe = GXRedirectWriteGatherPipe(verts);
|
||||
|
||||
x10_skinRules->InitLockedCacheState(**x4_model);
|
||||
x10_skinRules->BuildAccumulatedTransforms(pose, **x1c_layoutInfo);
|
||||
x10_skinRules->BuildPoints(pipe);
|
||||
|
||||
int numWords = x10_skinRules->GetNumPoints() * 3;
|
||||
int padWords = ((numWords + 7) & ~7) - numWords;
|
||||
for (int i = 0; i < padWords; i++) {
|
||||
*reinterpret_cast< volatile u32* >(pipe) = 0;
|
||||
}
|
||||
|
||||
x10_skinRules->BuildNormals(pipe);
|
||||
GXRestoreWriteGatherPipe();
|
||||
OSRestoreInterrupts(interruptState);
|
||||
|
||||
if (morphEffect.valid()) {
|
||||
(*morphEffect)
|
||||
.MorphVertices(reinterpret_cast< CVector3f* >(verts),
|
||||
reinterpret_cast< const CVector3f* >(averagedNormals), x10_skinRules, pose,
|
||||
x10_skinRules->GetNumPoints());
|
||||
DCFlushRange(verts, alignedVertSize);
|
||||
}
|
||||
|
||||
if (sPointGen != nullptr) {
|
||||
const CVector3f* positions = reinterpret_cast< const CVector3f* >(verts);
|
||||
sPointGen(sPointGenData, positions, positions + x10_skinRules->GetNumPoints(),
|
||||
x10_skinRules->GetNumPoints());
|
||||
DCInvalidateRange(verts, totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
void CSkinnedModel::CalculateDefault() {
|
||||
x28_vertWorkspace = rstl::auto_ptr< float >();
|
||||
x30_normalWorkspace = rstl::auto_ptr< float >();
|
||||
}
|
||||
|
||||
void CSkinnedModel::TickAllocations() {
|
||||
int syncVal = GXReadDrawSync();
|
||||
if (syncVal > static_cast< int >(Skinning::skCurrentToken)) {
|
||||
syncVal -= 0x10000;
|
||||
}
|
||||
while (Skinning::sAllocations.size() != 0) {
|
||||
SSkinnedAllocation& front = Skinning::sAllocations.front();
|
||||
int tokenVal = static_cast< int >(front.x8_unk2);
|
||||
if (tokenVal > static_cast< int >(Skinning::skCurrentToken)) {
|
||||
tokenVal -= 0x10000;
|
||||
}
|
||||
if (syncVal < tokenVal)
|
||||
break;
|
||||
Skinning::sSkinningBuffer->Free(front.x0_ptr, front.x4_unk1);
|
||||
Skinning::sAllocations.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void* CSkinnedModel::EnsureAllocation(int size) {
|
||||
size = (size + 31) & ~31;
|
||||
void* ptr = Skinning::sSkinningBuffer->Alloc(size);
|
||||
if (ptr == nullptr && !Skinning::sbDumpedSpinLockMessage) {
|
||||
Skinning::sSkinningBuffer->GetAllocatedAmount();
|
||||
Skinning::sbDumpedSpinLockMessage = true;
|
||||
}
|
||||
s32 startTick = OSGetTick();
|
||||
while (ptr == nullptr) {
|
||||
TickAllocations();
|
||||
ptr = Skinning::sSkinningBuffer->Alloc(size);
|
||||
if (ptr == nullptr) {
|
||||
s32 currentTick = OSGetTick();
|
||||
if (OSTicksToMilliseconds(static_cast< uint >(currentTick - startTick)) > 60) {
|
||||
GXReadDrawSync();
|
||||
for (AUTO(it, Skinning::sAllocations.begin()); it != Skinning::sAllocations.end(); ++it) {
|
||||
}
|
||||
startTick = currentTick;
|
||||
GXSetDrawSync(Skinning::skCurrentToken);
|
||||
++Skinning::skCurrentToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
Skinning::sAllocations.push_back(SSkinnedAllocation(ptr, size, Skinning::skCurrentToken));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void CSkinnedModel::AllocateStorage() {
|
||||
if (x38_owned && (x28_vertWorkspace.null() || x30_normalWorkspace.null())) {
|
||||
int vertexCount = x10_skinRules->GetNumPoints();
|
||||
int normalCount = x10_skinRules->GetNumNormals();
|
||||
TickAllocations();
|
||||
int normSize = (normalCount * 12 + 31) & ~31;
|
||||
int vertSize = (vertexCount * 12 + 31) & ~31;
|
||||
int totalSize = vertSize + normSize + 32;
|
||||
void* ptr = EnsureAllocation(totalSize);
|
||||
if (ptr == Skinning::sStaticSkinningData) {
|
||||
GXInvalidateVtxCache();
|
||||
}
|
||||
x28_vertWorkspace = rstl::auto_ptr< float >(static_cast< float* >(ptr));
|
||||
x30_normalWorkspace =
|
||||
rstl::auto_ptr< float >(reinterpret_cast< float* >(static_cast< char* >(ptr) + vertSize));
|
||||
x28_vertWorkspace.release();
|
||||
x30_normalWorkspace.release();
|
||||
}
|
||||
}
|
||||
|
||||
void CSkinnedModel::PostDrawFunc() const {
|
||||
if (x38_owned && !x28_vertWorkspace.null()) {
|
||||
x28_vertWorkspace = rstl::auto_ptr< float >();
|
||||
x30_normalWorkspace = rstl::auto_ptr< float >();
|
||||
GXSetDrawSync(Skinning::skCurrentToken);
|
||||
++Skinning::skCurrentToken;
|
||||
}
|
||||
}
|
||||
|
||||
void CSkinnedModel::AddDummySkinnedModelRef() { Skinning::AddSkinnedRef(); }
|
||||
|
||||
void CSkinnedModel::RemoveDummySkinnedModelRef() { Skinning::DelSkinnedRef(); }
|
||||
|
||||
void CSkinnedModel::SetPointGeneratorFunc(void* data, void (*func)(void*, const CVector3f*,
|
||||
const CVector3f*, int)) {
|
||||
sPointGen = func;
|
||||
sPointGenData = data;
|
||||
}
|
||||
|
||||
void CSkinnedModel::ClearPointGeneratorFunc() { sPointGen = nullptr; }
|
||||
|
||||
float* CSkinnedModel::AllocateNewWorkspace(float** vertOut) {
|
||||
const CSkinRules* skinRules = *x10_skinRules;
|
||||
int normalCount = skinRules->GetNumNormals();
|
||||
int vertexCount = skinRules->GetNumPoints();
|
||||
int alignedNormSize = (normalCount * 12 + 31) & ~31;
|
||||
int alignedVertSize = (vertexCount * 12 + 31) & ~31;
|
||||
int vertSize = vertexCount * 12;
|
||||
float* ptr = static_cast< float* >(
|
||||
CMemory::Alloc(((vertSize + 31) & ~31) + alignedNormSize, IAllocator::kHI_RoundUpLen));
|
||||
if (vertOut != nullptr) {
|
||||
*vertOut = reinterpret_cast< float* >(reinterpret_cast< char* >(ptr) + alignedNormSize);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user