1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
#ifndef NW4R_G3D_RES_RES_NODE_H
#define NW4R_G3D_RES_RES_NODE_H
#include <nw4r/types_nw4r.h>
#include "nw4r/g3d/res/g3d_rescommon.h"
#include "nw4r/math.h" // IWYU pragma: export
namespace nw4r {
namespace g3d {
// Forward declarations
struct ChrAnmResult;
/******************************************************************************
*
* Common types
*
******************************************************************************/
struct ResNodeDataTypedef {
enum Billboard {
BILLBOARD_OFF,
BILLBOARD_STD,
BILLBOARD_PERSP_STD,
BILLBOARD_ROT,
BILLBOARD_PERSP_ROT,
BILLBOARD_Y_OFF,
BILLBOARD_PERSP_Y,
NUM_BILLBOARD,
};
};
/******************************************************************************
*
* ResNode
*
******************************************************************************/
struct ResNodeData : ResNodeDataTypedef {
enum Flag {
FLAG_IDENTITY = (1 << 0),
FLAG_TRANS_ZERO = (1 << 1),
FLAG_ROT_ZERO = (1 << 2),
FLAG_SCALE_ONE = (1 << 3),
FLAG_SCALE_UNIFORM = (1 << 4),
// Maya Scale Compensation
FLAG_SSC_APPLY = (1 << 5),
FLAG_SSC_PARENT = (1 << 6),
// Softimage Hierarchical Scaling
FLAG_XSI_SCALING = (1 << 7),
FLAG_VISIBLE = (1 << 8),
FLAG_GEOMETRY = (1 << 9),
FLAG_BILLBOARD_PARENT = (1 << 10)
};
u32 size; // at 0x0
s32 toResMdlData; // at 0x4
s32 name; // at 0x8
u32 id; // at 0xC
u32 mtxID; // at 0x10
u32 flags; // at 0x14
Billboard bbmode; // at 0x18
u32 bbref_nodeid; // at 0x1C
math::_VEC3 scale; // at 0x20
math::_VEC3 rot; // at 0x2C
math::_VEC3 translate; // at 0x38
math::_VEC3 volume_min; // at 0x44
math::_VEC3 volume_max; // at 0x50
s32 toParentNode; // at 0x5C
s32 toChildNode; // at 0x60
s32 toNextSibling; // at 0x64
s32 toPrevSibling; // at 0x68
s32 toResUserData; // at 0x6C
math::_MTX34 modelMtx; // at 0x70
math::_MTX34 invModelMtx; // at 0xA0
};
class ResNode : public ResCommon<ResNodeData>, public ResNodeDataTypedef {
public:
NW4R_G3D_RESOURCE_FUNC_DEF(ResNode);
void PatchChrAnmResult(ChrAnmResult *pResult) const;
void CalcChrAnmResult(ChrAnmResult *pResult) const;
ResName GetResName() const {
const ResNodeData &r = ref();
if (r.name != 0) {
return NW4R_G3D_OFS_TO_RESNAME(&r, r.name);
}
return ResName(NULL);
}
const char *GetName() const {
const ResNodeData &r = ref();
return ofs_to_ptr<const char>(r.name);
}
u32 GetID() const {
if (IsValid()) {
return ptr()->id;
}
return 0;
}
u32 GetMtxID() const {
return IsValid() ? ptr()->mtxID : 0;
}
bool IsVisible() const {
if (IsValid()) {
return ptr()->flags & ResNodeData::FLAG_VISIBLE;
}
return false;
}
void SetVisibility(bool visible) {
if (!IsValid()) {
return;
}
if (visible) {
ptr()->flags |= ResNodeData::FLAG_VISIBLE;
} else {
ptr()->flags &= ~ResNodeData::FLAG_VISIBLE;
}
}
Billboard GetBillboardMode() const {
if (IsValid()) {
return ptr()->bbmode;
}
return BILLBOARD_OFF;
}
const math::VEC3 &GetTranslate() const {
return *(const math::VEC3 *)&ref().translate;
}
// not in the dwarf
const math::VEC3 &GetBoundsMin() const {
return *(const math::VEC3 *)&ref().volume_min;
}
// not in the dwarf
const math::VEC3 &GetBoundsMax() const {
return *(const math::VEC3 *)&ref().volume_max;
}
ResNode GetParentNode() {
return ofs_to_obj<ResNode>(ref().toParentNode);
}
ResNode GetParentNode() const {
return ofs_to_obj<ResNode>(ref().toParentNode);
}
ResNode GetChildNode() {
return ofs_to_obj<ResNode>(ref().toChildNode);
}
ResNode GetChildNode() const {
return ofs_to_obj<ResNode>(ref().toChildNode);
}
ResNode GetNextSibling() {
return ofs_to_obj<ResNode>(ref().toNextSibling);
}
ResNode GetNextSibling() const {
return ofs_to_obj<ResNode>(ref().toNextSibling);
}
ResNode GetPrevSibling() {
return ofs_to_obj<ResNode>(ref().toPrevSibling);
}
ResNode GetPrevSibling() const {
return ofs_to_obj<ResNode>(ref().toPrevSibling);
}
void EndEdit() {}
};
} // namespace g3d
} // namespace nw4r
#endif
|