-
Notifications
You must be signed in to change notification settings - Fork 1
NODE
Jocelyn Beedie edited this page Feb 17, 2021
·
18 revisions
A lot of data within the Node structure is dependent on the resource_id
.
struct Node {
int32_t parent_node_id; // 0 for root node
int32_t unknown_node_ids[3];
int32_t resource_id; // Depends on what this node is for; lighting nodes tend to use LIGHT files, particle nodes tend to use PARTICLE files, etc.
int32_t datatype_id; // Data type (see table below)
// if datatype_id != 0:
NodeDataUnion node_data; // Structure depends on datatype_id; has variable size
//
int32_t light_id; // LIGHT file, may be 0
int32_t hfog_id; // HFOG file, may be 0
uint32_t userdefine_id; // USERDEFINE file, may be 0
float floatv1[9]; // Unknown usage, related to transforms somehow
float floatv2[9]; // Unknown usage, related to transforms somehow
Mat4x4 local_transform;
Vector3 local_translation;
char junk[4];
Quaternion local_rotation;
Vector3 local_scale;
char junk2[4];
float unk1[2]; // Somehow related to sound, maybe distance attenuation? Always (0, 0) on nodes with no sound data
uint32_t unk2_1[4]; // Graphics chunk index?
uint32_t unk2_2[4]; // Collision chunk index?
float unk3[4]; // Always (0, 0, 0, 1)
uint16_t unk4[2]; // some kind of flag value?
Mat4x4 global_transform;
Mat4x4 global_transform_inverse;
}
union NodeDataUnion {
NodeDataLod lod; // variable size
NodeDataSkin skin; // variable size
NodeDataSurface surface; // 40B
NodeDataRotshape rotshape; // 62B
NodeDataMesh mesh; // 28B
NodeDataParticles particles; // 30B
}
struct NodeDataLod {
int32_t path_id;
int32_t subtype_id;
float unk1[5];
uint32_t num_unk2; // Always 1
int32_t data_type; // Either "MESHDATA" or "SKEL"
NodeDataUnion data; // variant depends on data_type
char unk2[100]; // I'll look through this later
int32_t node_id; // NODE reference, usually to parent
int32_t light1_id; // LIGHT reference
int32_t light2_id; // LIGHT reference, usually equal to light1_id
uint32_t num_nodes; // Usually 1
int32_t nodes[num_nodes]; // NODE reference(s)
uint32_t num_unk3;
uint32_t unk3[num_unk3];
}
struct NodeDataSkin {
int32_t path_id;
int32_t subtype_id;
float unk1[5];
uint32_t num_unk2;
NodeLodSkelUnk2 unk2[num_unk2];
int32_t unk3_id;
uint32_t num_materials;
NodeLodSkel_Material materials[num_materials];
uint32_t num_unk4;
NodeLodSkel_Unk unk4[num_unk4];
uint32_t num_unk5;
NodeLodSkel_Unk unk5[num_unk5];
uint32_t num_unk6;
NodeLodSkel_Unk unk6[num_unk6];
uint32_t num_unk7;
NodeLodSkelUnk7_Part1 unk7[num_unk7];
NodeLodSkelUnk7_Part2 unk7[num_unk7];
}
struct NodeDataSurface {
int32_t data_id;
int32_t subtype_id;
float data[5]; // Always {0.0, 0.0, 0.0, 1.0}
uint32_t num_unk1;
NodeDataSurfaceUnk unk1[num_unk1];
uint32_t num_unk2; // Always 0
uint32_t unk3;
}
struct NodeDataSurfaceUnk {
char unk[104];
}
struct NodeDataRotshape {
int32_t data_id;
int32_t subtype_id;
uint32_t unk1[6]; // Always {0, 0, 0, 0, 0, 1}
uint16_t unk2; // Always 0
char junk[28]; // first byte might not be junk? idk, this one is weird
}
struct NodeDataMesh {
int32_t data_id;
int32_t subtype_id;
float data[5]; // Always {0.0, 0.0, 0.0, 0.0, 1.0}
}
struct NodeDataParticles {
int32_t data_id;
int32_t subtype_id;
float unk1[5];
uint16_t unk2;
}
struct NodeLodSkelUnk2 {
int32_t unk_ids[5]; // IDs of some kind
int32_t extra_data_id; // If non-zero, then this structure includes extra data.
// if extra_data_id != 0:
NodeLodSkelUnk2ExtraDataUnion extra_data;
// end if
Vector3 local_translation;
char junk[4];
Quaternion local_rotation;
Vector3 local_scale;
float floatv1[9]; // Somehow related to transform
float floatv2[9]; // Somehow related to transform
Mat4x4 tx1;
Mat4x4 tx2;
}
union NodeLodSkelUnk2ExtraDataUnion {
NodeLodSkelUnk2ExtraData_UserDefine userdefine;
}
struct NodeLodSkelUnk2ExtraData_UserDefine {
int32_t userdefine_type; // Usually SKELDEFINE
int32_t userdefine_type; // Usually SKELDEFINE
uint32_t length;
char usedefine[length];
}
struct NodeLodSkel_Material {
int32_t filetype_id; // Same as in archive; always "MATERIAL" here.
int32_t filename_id; // Same as in archive
int32_t subtype_id; // Same as in archive
Material material;
}
struct NodeLodSkel_Unk {
float unk1[4];
int32_t unk2_id; // ID
int32_t unk3_id; // ID
}
struct NodeLodSkelUnk7_Part1 {
int32_t datatype_id; // Generally either"MESHDATA" or "SURFACEDATAS"
NodeDataUnion data; // Depends on datatype_id
}
struct NodeLodSkelUnk7_Part2 {
uint32_t num_ids;
int32_t ids[num_ids];
}
See: https://github.com/Jellonator/chum-world/wiki/MATERIAL
data_id
is often the hash of the string that subtype_id
hashes, but with "_DATA" concatenated to the end; for example, if subtype_id
is the hash of "GOOBUBBLEPOP", then data_id
is the hash of "GOOBUBBLEPOP_DATA".
Resource Type | datatype_id (hash of) |
---|---|
SURFACE | SURFACEDATA |
SKIN | SKEL |
ROTSHAPE | ROTSHAPEDATA |
LOD | LODDATA |
MESH | MESHDATA |
PARTICLES | PARTICLESDATA |