mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-11 08:36:38 -04:00
Define custom model parts as they arrive, instead of buffering them all into memory first
For 64 bit, reduces size of custom_models array from 802 to 465 kilobytes
This commit is contained in:
parent
4cf4db4607
commit
f2cfdb372d
46
src/Model.c
46
src/Model.c
@ -494,49 +494,39 @@ static void Models_TextureChanged(void* obj, struct Stream* stream, const String
|
||||
static struct VertexTextured defaultVertices[MODEL_BOX_VERTICES * MAX_CUSTOM_MODEL_PARTS];
|
||||
struct CustomModel custom_models[MAX_CUSTOM_MODELS];
|
||||
|
||||
void CustomModelPart_BuildBox(struct CustomModelPart* part) {
|
||||
void CustomModel_BuildPart(struct CustomModel* cm, struct CustomModelPartDef* part) {
|
||||
float x1 = part->min.X, y1 = part->min.Y, z1 = part->min.Z;
|
||||
float x2 = part->max.X, y2 = part->max.Y, z2 = part->max.Z;
|
||||
struct Model* m = Models.Active;
|
||||
|
||||
BoxDesc_YQuad2(m, x1, x2, z2, z1, y2, /* top */
|
||||
struct CustomModelPart* p = &cm->parts[cm->curPartIndex];
|
||||
cm->model.index = cm->curPartIndex * MODEL_BOX_VERTICES;
|
||||
p->fullbright = part->flags & 0x01;
|
||||
p->firstPersonArm = part->flags & 0x02;
|
||||
|
||||
BoxDesc_YQuad2(&cm->model, x1, x2, z2, z1, y2, /* top */
|
||||
part->u1[0], part->v1[0],
|
||||
part->u2[0], part->v2[0]);
|
||||
BoxDesc_YQuad2(m, x2, x1, z2, z1, y1, /* bottom */
|
||||
BoxDesc_YQuad2(&cm->model, x2, x1, z2, z1, y1, /* bottom */
|
||||
part->u1[1], part->v1[1],
|
||||
part->u2[1], part->v2[1]);
|
||||
BoxDesc_ZQuad2(m, x1, x2, y1, y2, z1, /* front */
|
||||
BoxDesc_ZQuad2(&cm->model, x1, x2, y1, y2, z1, /* front */
|
||||
part->u1[2], part->v1[2],
|
||||
part->u2[2], part->v2[2]);
|
||||
BoxDesc_ZQuad2(m, x2, x1, y1, y2, z2, /* back */
|
||||
BoxDesc_ZQuad2(&cm->model, x2, x1, y1, y2, z2, /* back */
|
||||
part->u1[3], part->v1[3],
|
||||
part->u2[3], part->v2[3]);
|
||||
BoxDesc_XQuad2(m, z1, z2, y1, y2, x2, /* left */
|
||||
BoxDesc_XQuad2(&cm->model, z1, z2, y1, y2, x2, /* left */
|
||||
part->u1[4], part->v1[4],
|
||||
part->u2[4], part->v2[4]);
|
||||
BoxDesc_XQuad2(m, z2, z1, y1, y2, x1, /* right */
|
||||
BoxDesc_XQuad2(&cm->model, z2, z1, y1, y2, x1, /* right */
|
||||
part->u1[5], part->v1[5],
|
||||
part->u2[5], part->v2[5]);
|
||||
|
||||
ModelPart_Init(
|
||||
&part->modelPart,
|
||||
m->index - MODEL_BOX_VERTICES,
|
||||
MODEL_BOX_VERTICES,
|
||||
part->rotationOrigin.X, part->rotationOrigin.Y, part->rotationOrigin.Z
|
||||
);
|
||||
}
|
||||
|
||||
/*#########################################*
|
||||
*-------------Model methods----------------*
|
||||
*##########################################*/
|
||||
static void CustomModel_MakeParts(void) {
|
||||
struct CustomModel* cm = (struct CustomModel*)Models.Active;
|
||||
int i;
|
||||
for (i = 0; i < cm->numParts; i++) {
|
||||
CustomModelPart_BuildBox(&cm->parts[i]);
|
||||
}
|
||||
ModelPart_Init(&p->modelPart, cm->model.index - MODEL_BOX_VERTICES, MODEL_BOX_VERTICES,
|
||||
part->rotationOrigin.X, part->rotationOrigin.Y, part->rotationOrigin.Z);
|
||||
}
|
||||
|
||||
static void CustomModel_MakeParts(void) { }
|
||||
static struct ModelVertex oldVertices[MODEL_BOX_VERTICES];
|
||||
static float CustomModel_GetAnimationValue(
|
||||
struct CustomModelAnim* anim,
|
||||
@ -752,9 +742,6 @@ static void CustomModel_DrawArm(struct Entity* e) {
|
||||
if (cm->model.index) Model_UpdateVB();
|
||||
}
|
||||
|
||||
/*#########################################*
|
||||
*-----------Init/Free functions------------*
|
||||
*##########################################*/
|
||||
static void CheckMaxVertices(void) {
|
||||
/* hack to undo plugins setting a smaller vertices buffer */
|
||||
if (Models.MaxVertices < Array_Elems(defaultVertices)) {
|
||||
@ -773,7 +760,6 @@ void CustomModel_Register(struct CustomModel* cm) {
|
||||
|
||||
CheckMaxVertices();
|
||||
cm->model.name = cm->name;
|
||||
cm->model.vertices = cm->vertices;
|
||||
cm->model.defaultTex = &customDefaultTex;
|
||||
|
||||
cm->model.MakeParts = CustomModel_MakeParts;
|
||||
@ -799,7 +785,7 @@ void CustomModel_Undefine(struct CustomModel* cm) {
|
||||
if (!cm->defined) return;
|
||||
if (cm->registered) Model_Unregister((struct Model*)cm);
|
||||
|
||||
Mem_Free(cm->vertices);
|
||||
Mem_Free(cm->model.vertices);
|
||||
Mem_Set(cm, 0, sizeof(struct CustomModel));
|
||||
}
|
||||
|
||||
|
29
src/Model.h
29
src/Model.h
@ -239,34 +239,24 @@ struct CustomModelAnim {
|
||||
float a, b, c, d;
|
||||
};
|
||||
|
||||
struct CustomModelPartDef {
|
||||
Vec3 min, max;
|
||||
/* uv coords in order: top, bottom, front, back, left, right */
|
||||
cc_uint16 u1[6], v1[6], u2[6], v2[6];
|
||||
Vec3 rotationOrigin;
|
||||
cc_uint8 flags;
|
||||
};
|
||||
|
||||
struct CustomModelPart {
|
||||
struct ModelPart modelPart;
|
||||
|
||||
/* min and max vec3 points */
|
||||
Vec3 min;
|
||||
Vec3 max;
|
||||
|
||||
/* uv coords in order: top, bottom, front, back, left, right */
|
||||
cc_uint16 u1[6];
|
||||
cc_uint16 v1[6];
|
||||
cc_uint16 u2[6];
|
||||
cc_uint16 v2[6];
|
||||
/* rotation origin point */
|
||||
Vec3 rotationOrigin;
|
||||
|
||||
/* rotation angles */
|
||||
Vec3 rotation;
|
||||
|
||||
Vec3 rotation; /* rotation angles */
|
||||
struct CustomModelAnim anims[MAX_CUSTOM_MODEL_ANIMS];
|
||||
|
||||
cc_bool fullbright;
|
||||
cc_bool firstPersonArm;
|
||||
};
|
||||
|
||||
struct CustomModel {
|
||||
struct Model model;
|
||||
struct ModelVertex* vertices;
|
||||
|
||||
char name[STRING_SIZE + 1];
|
||||
|
||||
float nameY;
|
||||
@ -287,6 +277,7 @@ struct CustomModel {
|
||||
|
||||
extern struct CustomModel custom_models[MAX_CUSTOM_MODELS];
|
||||
|
||||
void CustomModel_BuildPart(struct CustomModel* cm, struct CustomModelPartDef* part);
|
||||
void CustomModel_Register(struct CustomModel* cm);
|
||||
void CustomModel_Undefine(struct CustomModel* cm);
|
||||
|
||||
|
@ -1456,7 +1456,7 @@ static void CPE_DefineModel(cc_uint8* data) {
|
||||
}
|
||||
|
||||
cm->numParts = numParts;
|
||||
cm->vertices = Mem_AllocCleared(
|
||||
cm->model.vertices = Mem_AllocCleared(
|
||||
numParts * MODEL_BOX_VERTICES,
|
||||
sizeof(struct ModelVertex),
|
||||
"CustomModel vertices"
|
||||
@ -1465,35 +1465,33 @@ static void CPE_DefineModel(cc_uint8* data) {
|
||||
}
|
||||
|
||||
static void CPE_DefineModelPart(cc_uint8* data) {
|
||||
/* 103 = 1 + 3*4 + 3*4 + 6*(2*2 + 2*2) + 3*4 + 3*4 + 1 + 4 + 1 */
|
||||
cc_uint8 id = data[0];
|
||||
struct CustomModel* m = &custom_models[id];
|
||||
struct CustomModelPart* part;
|
||||
cc_uint8 flags;
|
||||
struct CustomModelPartDef p;
|
||||
int i;
|
||||
|
||||
if (id >= MAX_CUSTOM_MODELS || !m->defined || m->curPartIndex >= m->numParts) return;
|
||||
part = &m->parts[m->curPartIndex];
|
||||
m->curPartIndex++;
|
||||
|
||||
part->min.X = GetFloat(data + 1);
|
||||
part->min.Y = GetFloat(data + 5);
|
||||
part->min.Z = GetFloat(data + 9);
|
||||
part->max.X = GetFloat(data + 13);
|
||||
part->max.Y = GetFloat(data + 17);
|
||||
part->max.Z = GetFloat(data + 21);
|
||||
p.min.X = GetFloat(data + 1);
|
||||
p.min.Y = GetFloat(data + 5);
|
||||
p.min.Z = GetFloat(data + 9);
|
||||
p.max.X = GetFloat(data + 13);
|
||||
p.max.Y = GetFloat(data + 17);
|
||||
p.max.Z = GetFloat(data + 21);
|
||||
|
||||
/* read u, v coords for our 6 faces */
|
||||
for (i = 0; i < 6; i++) {
|
||||
part->u1[i] = Stream_GetU16_BE(data + 25 + (i*8 + 0));
|
||||
part->v1[i] = Stream_GetU16_BE(data + 25 + (i*8 + 2));
|
||||
part->u2[i] = Stream_GetU16_BE(data + 25 + (i*8 + 4));
|
||||
part->v2[i] = Stream_GetU16_BE(data + 25 + (i*8 + 6));
|
||||
p.u1[i] = Stream_GetU16_BE(data + 25 + (i*8 + 0));
|
||||
p.v1[i] = Stream_GetU16_BE(data + 25 + (i*8 + 2));
|
||||
p.u2[i] = Stream_GetU16_BE(data + 25 + (i*8 + 4));
|
||||
p.v2[i] = Stream_GetU16_BE(data + 25 + (i*8 + 6));
|
||||
}
|
||||
|
||||
part->rotationOrigin.X = GetFloat(data + 73);
|
||||
part->rotationOrigin.Y = GetFloat(data + 77);
|
||||
part->rotationOrigin.Z = GetFloat(data + 81);
|
||||
p.rotationOrigin.X = GetFloat(data + 73);
|
||||
p.rotationOrigin.Y = GetFloat(data + 77);
|
||||
p.rotationOrigin.Z = GetFloat(data + 81);
|
||||
|
||||
part->rotation.X = GetFloat(data + 85);
|
||||
part->rotation.Y = GetFloat(data + 89);
|
||||
@ -1501,10 +1499,11 @@ static void CPE_DefineModelPart(cc_uint8* data) {
|
||||
|
||||
if (cpe_customModelsVer == 1) {
|
||||
/* ignore animations */
|
||||
data += 102;
|
||||
p.flags = data[102];
|
||||
} else if (cpe_customModelsVer == 2) {
|
||||
data += 97;
|
||||
p.flags = data[165];
|
||||
|
||||
data += 97;
|
||||
for (i = 0; i < MAX_CUSTOM_MODEL_ANIMS; i++) {
|
||||
cc_uint8 tmp = *data++;
|
||||
part->anims[i].type = tmp & 0x3F;
|
||||
@ -1521,14 +1520,9 @@ static void CPE_DefineModelPart(cc_uint8* data) {
|
||||
}
|
||||
}
|
||||
|
||||
flags = *data;
|
||||
part->fullbright = flags & 0x01;
|
||||
part->firstPersonArm = flags & 0x02;
|
||||
|
||||
if (m->curPartIndex == m->numParts) {
|
||||
/* we're the last part, so register our model */
|
||||
CustomModel_Register(m);
|
||||
}
|
||||
CustomModel_BuildPart(m, &p);
|
||||
m->curPartIndex++;
|
||||
if (m->curPartIndex == m->numParts) CustomModel_Register(m);
|
||||
}
|
||||
|
||||
/* unregisters and frees the custom model */
|
||||
|
Loading…
x
Reference in New Issue
Block a user