mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-09 15:28:21 -04:00
commit
eb68cb9026
232
src/Model.c
232
src/Model.c
@ -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();
|
||||
|
44
src/Model.h
44
src/Model.h
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user