From f2cfdb372dedd181244f2750809c574067a27e05 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 1 Aug 2020 11:07:48 +1000 Subject: [PATCH] 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 --- src/Model.c | 46 ++++++++++++++++------------------------------ src/Model.h | 29 ++++++++++------------------- src/Protocol.c | 48 +++++++++++++++++++++--------------------------- 3 files changed, 47 insertions(+), 76 deletions(-) diff --git a/src/Model.c b/src/Model.c index bfb9011a2..bfbea7889 100644 --- a/src/Model.c +++ b/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)); } diff --git a/src/Model.h b/src/Model.h index a2fafcfb4..6f5be58f4 100644 --- a/src/Model.h +++ b/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); diff --git a/src/Protocol.c b/src/Protocol.c index 3763bb756..c1b9f3e2a 100644 --- a/src/Protocol.c +++ b/src/Protocol.c @@ -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 */