Merge pull request #688 from SpiralP/master

Custom Models v2
This commit is contained in:
UnknownShadow200 2020-07-07 19:19:15 +10:00 committed by GitHub
commit eb68cb9026
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 224 additions and 86 deletions

View File

@ -551,24 +551,84 @@ static void CustomModel_MakeParts(void) {
} }
} }
struct ModelVertex oldVertices[MODEL_BOX_VERTICES];
static float CustomModel_GetAnimationValue(
struct CustomModelAnim* anim,
struct CustomModelPart* part,
struct CustomModel* cm,
struct Entity* e
) {
switch (anim->type) {
case CustomModelAnimType_Head:
return -e->Pitch * MATH_DEG2RAD;
case CustomModelAnimType_LeftLegX:
return e->Anim.LeftLegX;
case CustomModelAnimType_RightLegX:
return e->Anim.RightLegX;
case CustomModelAnimType_LeftArmX:
/* TODO: we're using 2 different rotation orders here */
Models.Rotation = ROTATE_ORDER_XZY;
return e->Anim.LeftArmX;
case CustomModelAnimType_LeftArmZ:
Models.Rotation = ROTATE_ORDER_XZY;
return e->Anim.LeftArmZ;
case CustomModelAnimType_RightArmX:
Models.Rotation = ROTATE_ORDER_XZY;
return e->Anim.RightArmX;
case CustomModelAnimType_RightArmZ:
Models.Rotation = ROTATE_ORDER_XZY;
return e->Anim.RightArmZ;
/*
a: speed
b: shift pos
*/
case CustomModelAnimType_Spin:
return (float)Game.Time * anim->a + anim->b;
case CustomModelAnimType_SpinVelocity:
return e->Anim.WalkTime * anim->a + anim->b;
/*
a: speed
b: width
c: shift cycle
d: shift pos
*/
case CustomModelAnimType_SinRotate:
case CustomModelAnimType_SinTranslate:
return ( Math_SinF((float)Game.Time * anim->a + 2 * MATH_PI * anim->c) + anim->d ) * anim->b;
case CustomModelAnimType_SinRotateVelocity:
case CustomModelAnimType_SinTranslateVelocity:
return ( Math_SinF(e->Anim.WalkTime * anim->a + 2 * MATH_PI * anim->c) + anim->d ) * anim->b;
}
return 0.0f;
}
static PackedCol oldCols[FACE_COUNT]; static PackedCol oldCols[FACE_COUNT];
static void CustomModel_Draw(struct Entity* e) { static void CustomModel_DrawPart(
int i, j; struct CustomModelPart* part,
struct CustomModel* cm = (struct CustomModel*)Models.Active; struct CustomModel* cm,
struct Entity* e
Model_ApplyTexture(e); ) {
Models.uScale = 1.0f / cm->uScale; int i, animIndex;
Models.vScale = 1.0f / cm->vScale;
for (i = 0; i < cm->numParts; i++) {
float rotX, rotY, rotZ; float rotX, rotY, rotZ;
cc_bool head; cc_bool head = false;
struct CustomModelPart* part = &cm->parts[i]; cc_bool modifiedVertices = false;
float value = 0.0f;
if (part->fullbright) { if (part->fullbright) {
for (j = 0; j < FACE_COUNT; j++) { for (i = 0; i < FACE_COUNT; i++) {
oldCols[j] = Models.Cols[j]; oldCols[i] = Models.Cols[i];
Models.Cols[j] = PACKEDCOL_WHITE; Models.Cols[i] = PACKEDCOL_WHITE;
} }
} }
@ -578,51 +638,95 @@ static void CustomModel_Draw(struct Entity* e) {
rotX = part->rotation.X * MATH_DEG2RAD; rotX = part->rotation.X * MATH_DEG2RAD;
rotY = part->rotation.Y * MATH_DEG2RAD; rotY = part->rotation.Y * MATH_DEG2RAD;
rotZ = part->rotation.Z * MATH_DEG2RAD; rotZ = part->rotation.Z * MATH_DEG2RAD;
head = false;
if (part->anim == CustomModelAnim_Head) { for (animIndex = 0; animIndex < MAX_CUSTOM_MODEL_ANIMS; animIndex++) {
struct CustomModelAnim* anim = &part->anims[animIndex];
if (anim->type == CustomModelAnimType_None) {
continue;
}
value = CustomModel_GetAnimationValue(anim, part, cm, e);
if (
anim->type == CustomModelAnimType_SinTranslate ||
anim->type == CustomModelAnimType_SinTranslateVelocity
) {
if (!modifiedVertices) {
modifiedVertices = true;
Mem_Copy(
oldVertices,
&cm->model.vertices[part->modelPart.offset],
sizeof(struct ModelVertex) * MODEL_BOX_VERTICES
);
}
for (i = 0; i < MODEL_BOX_VERTICES; i++) {
switch (anim->axis) {
case CustomModelAnimAxis_X:
cm->model.vertices[part->modelPart.offset + i].X += value;
break;
case CustomModelAnimAxis_Y:
cm->model.vertices[part->modelPart.offset + i].Y += value;
break;
case CustomModelAnimAxis_Z:
cm->model.vertices[part->modelPart.offset + i].Z += value;
break;
}
}
} else {
if (anim->type == CustomModelAnimType_Head) {
head = true; head = true;
rotX += -e->Pitch * MATH_DEG2RAD; }
} else if (part->anim == CustomModelAnim_LeftLeg) {
rotX += e->Anim.LeftLegX; switch (anim->axis) {
rotZ += e->Anim.LeftLegZ; case CustomModelAnimAxis_X:
} else if (part->anim == CustomModelAnim_RightLeg) { rotX += value;
rotX += e->Anim.RightLegX; break;
rotZ += e->Anim.RightLegZ;
} else if (part->anim == CustomModelAnim_LeftArm) { case CustomModelAnimAxis_Y:
/* TODO: we're using 2 different rotation orders here */ rotY += value;
Models.Rotation = ROTATE_ORDER_XZY; break;
rotX += e->Anim.LeftArmX;
rotZ += e->Anim.LeftArmZ; case CustomModelAnimAxis_Z:
} else if (part->anim == CustomModelAnim_RightArm) { rotZ += value;
Models.Rotation = ROTATE_ORDER_XZY; break;
rotX += e->Anim.RightArmX; }
rotZ += e->Anim.RightArmZ; }
} else if (part->anim == CustomModelAnim_SpinX) {
rotX += (float)(Game.Time * part->animModifier);
} else if (part->anim == CustomModelAnim_SpinY) {
rotY += (float)(Game.Time * part->animModifier);
} else if (part->anim == CustomModelAnim_SpinZ) {
rotZ += (float)(Game.Time * part->animModifier);
} else if (part->anim == CustomModelAnim_SpinXVelocity) {
rotX += e->Anim.WalkTime * part->animModifier;
} else if (part->anim == CustomModelAnim_SpinYVelocity) {
rotY += e->Anim.WalkTime * part->animModifier;
} else if (part->anim == CustomModelAnim_SpinZVelocity) {
rotZ += e->Anim.WalkTime * part->animModifier;
} }
if (rotX || rotY || rotZ || head) { if (rotX || rotY || rotZ || head) {
Model_DrawRotate(rotX, rotY, rotZ, &cm->parts[i].modelPart, head); Model_DrawRotate(rotX, rotY, rotZ, &part->modelPart, head);
} else { } else {
Model_DrawPart(&cm->parts[i].modelPart); Model_DrawPart(&part->modelPart);
}
if (modifiedVertices) {
Mem_Copy(
&cm->model.vertices[part->modelPart.offset],
oldVertices,
sizeof(struct ModelVertex) * MODEL_BOX_VERTICES
);
} }
if (part->fullbright) { if (part->fullbright) {
for (j = 0; j < FACE_COUNT; j++) { for (i = 0; i < FACE_COUNT; i++) {
Models.Cols[j] = oldCols[j]; Models.Cols[i] = oldCols[i];
} }
} }
}
static void CustomModel_Draw(struct Entity* e) {
struct CustomModel* cm = (struct CustomModel*)Models.Active;
int partIndex;
Model_ApplyTexture(e);
Models.uScale = 1.0f / cm->uScale;
Models.vScale = 1.0f / cm->vScale;
for (partIndex = 0; partIndex < cm->numParts; partIndex++) {
CustomModel_DrawPart(&cm->parts[partIndex], cm, e);
} }
Model_UpdateVB(); Model_UpdateVB();

View File

@ -211,20 +211,35 @@ CC_API void BoxDesc_ZQuad2(struct Model* m, float x1, float x2, float y1, float
#define MAX_CUSTOM_MODELS 64 #define MAX_CUSTOM_MODELS 64
#define MAX_CUSTOM_MODEL_PARTS 64 #define MAX_CUSTOM_MODEL_PARTS 64
#define MAX_CUSTOM_MODEL_ANIMS 4
enum CustomModelAnim { enum CustomModelAnimType {
CustomModelAnim_None = 0, CustomModelAnimType_None = 0,
CustomModelAnim_Head = 1, CustomModelAnimType_Head = 1,
CustomModelAnim_LeftLeg = 2, CustomModelAnimType_LeftLegX = 2,
CustomModelAnim_RightLeg = 3, CustomModelAnimType_RightLegX = 3,
CustomModelAnim_LeftArm = 4, CustomModelAnimType_LeftArmX = 4,
CustomModelAnim_RightArm = 5, CustomModelAnimType_LeftArmZ = 5,
CustomModelAnim_SpinX = 6, CustomModelAnimType_RightArmX = 6,
CustomModelAnim_SpinY = 7, CustomModelAnimType_RightArmZ = 7,
CustomModelAnim_SpinZ = 8, CustomModelAnimType_Spin = 8,
CustomModelAnim_SpinXVelocity = 9, CustomModelAnimType_SpinVelocity = 9,
CustomModelAnim_SpinYVelocity = 10, CustomModelAnimType_SinRotate = 10,
CustomModelAnim_SpinZVelocity = 11 CustomModelAnimType_SinRotateVelocity = 11,
CustomModelAnimType_SinTranslate = 12,
CustomModelAnimType_SinTranslateVelocity = 13
};
enum CustomModelAnimAxis {
CustomModelAnimAxis_X = 0,
CustomModelAnimAxis_Y = 1,
CustomModelAnimAxis_Z = 2,
};
struct CustomModelAnim {
cc_uint8 type;
cc_uint8 axis;
float a, b, c, d;
}; };
struct CustomModelPart { struct CustomModelPart {
@ -245,8 +260,7 @@ struct CustomModelPart {
/* rotation angles */ /* rotation angles */
Vec3 rotation; Vec3 rotation;
float animModifier; struct CustomModelAnim anims[MAX_CUSTOM_MODEL_ANIMS];
cc_uint8 anim;
cc_bool fullbright; cc_bool fullbright;
cc_bool firstPersonArm; cc_bool firstPersonArm;

View File

@ -60,7 +60,7 @@ static struct MapState map2;
/* CPE state */ /* CPE state */
cc_bool cpe_needD3Fix; cc_bool cpe_needD3Fix;
static int cpe_serverExtensionsCount, cpe_pingTicks; static int cpe_serverExtensionsCount, cpe_pingTicks;
static int cpe_envMapVer = 2, cpe_blockDefsExtVer = 2; static int cpe_envMapVer = 2, cpe_blockDefsExtVer = 2, cpe_customModelsVer = 2;
static cc_bool cpe_sendHeldBlock, cpe_useMessageTypes, cpe_extEntityPos, cpe_blockPerms, cpe_fastMap; static cc_bool cpe_sendHeldBlock, cpe_useMessageTypes, cpe_extEntityPos, cpe_blockPerms, cpe_fastMap;
static cc_bool cpe_twoWayPing, cpe_extTextures, cpe_extBlocks; static cc_bool cpe_twoWayPing, cpe_extTextures, cpe_extBlocks;
@ -851,6 +851,7 @@ static void CPE_SendCpeExtInfoReply(void) {
if (String_CaselessEqualsConst(&name, "ExtPlayerList")) ver = 2; if (String_CaselessEqualsConst(&name, "ExtPlayerList")) ver = 2;
if (String_CaselessEqualsConst(&name, "EnvMapAppearance")) ver = cpe_envMapVer; if (String_CaselessEqualsConst(&name, "EnvMapAppearance")) ver = cpe_envMapVer;
if (String_CaselessEqualsConst(&name, "BlockDefinitionsExt")) ver = cpe_blockDefsExtVer; if (String_CaselessEqualsConst(&name, "BlockDefinitionsExt")) ver = cpe_blockDefsExtVer;
if (String_CaselessEqualsConst(&name, "CustomModels")) ver = cpe_customModelsVer;
if (!Game_AllowCustomBlocks) { if (!Game_AllowCustomBlocks) {
if (String_CaselessEqualsConst(&name, "BlockDefinitionsExt")) continue; if (String_CaselessEqualsConst(&name, "BlockDefinitionsExt")) continue;
@ -924,6 +925,11 @@ static void CPE_ExtEntry(cc_uint8* data) {
} else if (String_CaselessEqualsConst(&ext, "FastMap")) { } else if (String_CaselessEqualsConst(&ext, "FastMap")) {
Net_PacketSizes[OPCODE_LEVEL_BEGIN] += 4; Net_PacketSizes[OPCODE_LEVEL_BEGIN] += 4;
cpe_fastMap = true; cpe_fastMap = true;
} else if (String_CaselessEqualsConst(&ext, "CustomModels")) {
cpe_customModelsVer = min(2, version);
if (version == 2) {
Net_PacketSizes[OPCODE_DEFINE_MODEL_PART] = 167;
}
} }
#ifdef EXTENDED_TEXTURES #ifdef EXTENDED_TEXTURES
else if (String_CaselessEqualsConst(&ext, "ExtendedTextures")) { else if (String_CaselessEqualsConst(&ext, "ExtendedTextures")) {
@ -1521,12 +1527,26 @@ static void CPE_DefineModelPart(cc_uint8* data) {
part->rotation.Z = GetFloat(data); part->rotation.Z = GetFloat(data);
data += 4; data += 4;
/* read anim */ if (cpe_customModelsVer == 1) {
part->anim = *data++; /* ignore animations */
data++;
/* read animModifier */
part->animModifier = GetFloat(data);
data += 4; data += 4;
} else if (cpe_customModelsVer == 2) {
for (i = 0; i < MAX_CUSTOM_MODEL_ANIMS; i++) {
cc_uint8 tmp = *data++;
part->anims[i].type = tmp & 0x3F;
part->anims[i].axis = tmp >> 6;
part->anims[i].a = GetFloat(data);
data += 4;
part->anims[i].b = GetFloat(data);
data += 4;
part->anims[i].c = GetFloat(data);
data += 4;
part->anims[i].d = GetFloat(data);
data += 4;
}
}
/* read bool flags */ /* read bool flags */
flags = *data++; flags = *data++;
@ -1548,7 +1568,7 @@ static void CPE_UndefineModel(cc_uint8* data) {
static void CPE_Reset(void) { static void CPE_Reset(void) {
cpe_serverExtensionsCount = 0; cpe_pingTicks = 0; cpe_serverExtensionsCount = 0; cpe_pingTicks = 0;
cpe_sendHeldBlock = false; cpe_useMessageTypes = false; cpe_sendHeldBlock = false; cpe_useMessageTypes = false;
cpe_envMapVer = 2; cpe_blockDefsExtVer = 2; cpe_envMapVer = 2; cpe_blockDefsExtVer = 2; cpe_customModelsVer = 2;
cpe_needD3Fix = false; cpe_extEntityPos = false; cpe_twoWayPing = false; cpe_needD3Fix = false; cpe_extEntityPos = false; cpe_twoWayPing = false;
cpe_extTextures = false; cpe_fastMap = false; cpe_extBlocks = false; cpe_extTextures = false; cpe_fastMap = false; cpe_extBlocks = false;
Game_UseCPEBlocks = false; Game_UseCPEBlocks = false;