mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-10 07:49:57 -04:00
commit
eb68cb9026
200
src/Model.c
200
src/Model.c
@ -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,53 +638,97 @@ 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();
|
||||||
Models.Rotation = ROTATE_ORDER_ZYX;
|
Models.Rotation = ROTATE_ORDER_ZYX;
|
||||||
}
|
}
|
||||||
|
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_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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user