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,78 +551,182 @@ 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 void CustomModel_DrawPart(
struct CustomModelPart* part,
struct CustomModel* cm,
struct Entity* e
) {
int i, animIndex;
float rotX, rotY, rotZ;
cc_bool head = false;
cc_bool modifiedVertices = false;
float value = 0.0f;
if (part->fullbright) {
for (i = 0; i < FACE_COUNT; i++) {
oldCols[i] = Models.Cols[i];
Models.Cols[i] = PACKEDCOL_WHITE;
}
}
/* bbmodels use xyz rotation order */
Models.Rotation = ROTATE_ORDER_XYZ;
rotX = part->rotation.X * MATH_DEG2RAD;
rotY = part->rotation.Y * MATH_DEG2RAD;
rotZ = part->rotation.Z * MATH_DEG2RAD;
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;
}
switch (anim->axis) {
case CustomModelAnimAxis_X:
rotX += value;
break;
case CustomModelAnimAxis_Y:
rotY += value;
break;
case CustomModelAnimAxis_Z:
rotZ += value;
break;
}
}
}
if (rotX || rotY || rotZ || head) {
Model_DrawRotate(rotX, rotY, rotZ, &part->modelPart, head);
} else {
Model_DrawPart(&part->modelPart);
}
if (modifiedVertices) {
Mem_Copy(
&cm->model.vertices[part->modelPart.offset],
oldVertices,
sizeof(struct ModelVertex) * MODEL_BOX_VERTICES
);
}
if (part->fullbright) {
for (i = 0; i < FACE_COUNT; i++) {
Models.Cols[i] = oldCols[i];
}
}
}
static void CustomModel_Draw(struct Entity* e) {
int i, j;
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 (i = 0; i < cm->numParts; i++) {
float rotX, rotY, rotZ;
cc_bool head;
struct CustomModelPart* part = &cm->parts[i];
if (part->fullbright) {
for (j = 0; j < FACE_COUNT; j++) {
oldCols[j] = Models.Cols[j];
Models.Cols[j] = PACKEDCOL_WHITE;
}
}
/* bbmodels use xyz rotation order */
Models.Rotation = ROTATE_ORDER_XYZ;
rotX = part->rotation.X * MATH_DEG2RAD;
rotY = part->rotation.Y * MATH_DEG2RAD;
rotZ = part->rotation.Z * MATH_DEG2RAD;
head = false;
if (part->anim == CustomModelAnim_Head) {
head = true;
rotX += -e->Pitch * MATH_DEG2RAD;
} else if (part->anim == CustomModelAnim_LeftLeg) {
rotX += e->Anim.LeftLegX;
rotZ += e->Anim.LeftLegZ;
} else if (part->anim == CustomModelAnim_RightLeg) {
rotX += e->Anim.RightLegX;
rotZ += e->Anim.RightLegZ;
} else if (part->anim == CustomModelAnim_LeftArm) {
/* TODO: we're using 2 different rotation orders here */
Models.Rotation = ROTATE_ORDER_XZY;
rotX += e->Anim.LeftArmX;
rotZ += e->Anim.LeftArmZ;
} else if (part->anim == CustomModelAnim_RightArm) {
Models.Rotation = ROTATE_ORDER_XZY;
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) {
Model_DrawRotate(rotX, rotY, rotZ, &cm->parts[i].modelPart, head);
} else {
Model_DrawPart(&cm->parts[i].modelPart);
}
if (part->fullbright) {
for (j = 0; j < FACE_COUNT; j++) {
Models.Cols[j] = oldCols[j];
}
}
for (partIndex = 0; partIndex < cm->numParts; partIndex++) {
CustomModel_DrawPart(&cm->parts[partIndex], cm, e);
}
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_MODEL_PARTS 64
#define MAX_CUSTOM_MODEL_ANIMS 4
enum CustomModelAnim {
CustomModelAnim_None = 0,
CustomModelAnim_Head = 1,
CustomModelAnim_LeftLeg = 2,
CustomModelAnim_RightLeg = 3,
CustomModelAnim_LeftArm = 4,
CustomModelAnim_RightArm = 5,
CustomModelAnim_SpinX = 6,
CustomModelAnim_SpinY = 7,
CustomModelAnim_SpinZ = 8,
CustomModelAnim_SpinXVelocity = 9,
CustomModelAnim_SpinYVelocity = 10,
CustomModelAnim_SpinZVelocity = 11
enum CustomModelAnimType {
CustomModelAnimType_None = 0,
CustomModelAnimType_Head = 1,
CustomModelAnimType_LeftLegX = 2,
CustomModelAnimType_RightLegX = 3,
CustomModelAnimType_LeftArmX = 4,
CustomModelAnimType_LeftArmZ = 5,
CustomModelAnimType_RightArmX = 6,
CustomModelAnimType_RightArmZ = 7,
CustomModelAnimType_Spin = 8,
CustomModelAnimType_SpinVelocity = 9,
CustomModelAnimType_SinRotate = 10,
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 {
@ -245,8 +260,7 @@ struct CustomModelPart {
/* rotation angles */
Vec3 rotation;
float animModifier;
cc_uint8 anim;
struct CustomModelAnim anims[MAX_CUSTOM_MODEL_ANIMS];
cc_bool fullbright;
cc_bool firstPersonArm;

View File

@ -60,7 +60,7 @@ static struct MapState map2;
/* CPE state */
cc_bool cpe_needD3Fix;
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_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, "EnvMapAppearance")) ver = cpe_envMapVer;
if (String_CaselessEqualsConst(&name, "BlockDefinitionsExt")) ver = cpe_blockDefsExtVer;
if (String_CaselessEqualsConst(&name, "CustomModels")) ver = cpe_customModelsVer;
if (!Game_AllowCustomBlocks) {
if (String_CaselessEqualsConst(&name, "BlockDefinitionsExt")) continue;
@ -924,6 +925,11 @@ static void CPE_ExtEntry(cc_uint8* data) {
} else if (String_CaselessEqualsConst(&ext, "FastMap")) {
Net_PacketSizes[OPCODE_LEVEL_BEGIN] += 4;
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
else if (String_CaselessEqualsConst(&ext, "ExtendedTextures")) {
@ -1521,12 +1527,26 @@ static void CPE_DefineModelPart(cc_uint8* data) {
part->rotation.Z = GetFloat(data);
data += 4;
/* read anim */
part->anim = *data++;
if (cpe_customModelsVer == 1) {
/* ignore animations */
data++;
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;
/* read animModifier */
part->animModifier = GetFloat(data);
data += 4;
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 */
flags = *data++;
@ -1548,7 +1568,7 @@ static void CPE_UndefineModel(cc_uint8* data) {
static void CPE_Reset(void) {
cpe_serverExtensionsCount = 0; cpe_pingTicks = 0;
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_extTextures = false; cpe_fastMap = false; cpe_extBlocks = false;
Game_UseCPEBlocks = false;