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:
UnknownShadow200 2020-08-01 11:07:48 +10:00
parent 4cf4db4607
commit f2cfdb372d
3 changed files with 47 additions and 76 deletions

View File

@ -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));
}

View File

@ -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);

View File

@ -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 */