Finish porting ModelBuilder to C.

This commit is contained in:
UnknownShadow200 2017-06-17 10:57:37 +10:00
parent 58b979a81a
commit 39ad2de811
8 changed files with 203 additions and 7 deletions

View File

@ -8,6 +8,9 @@ using OpenTK;
namespace ClassicalSharp.Model {
/// <summary> Describes the type of skin that a humanoid model uses. </summary>
public enum SkinType { Type64x32, Type64x64, Type64x64Slim, Invalid }
/// <summary> Contains a set of quads and/or boxes that describe a 3D object as well as
/// the bounding boxes that contain the entire set of quads and/or boxes. </summary>
public abstract class IModel {

View File

@ -26,7 +26,4 @@ namespace ClassicalSharp.Model {
U = (ushort)u; V = (ushort)v;
}
}
/// <summary> Describes the type of skin that a humanoid model uses. </summary>
public enum SkinType { Type64x32, Type64x64, Type64x64Slim, Invalid }
}

View File

@ -196,6 +196,7 @@
<ClInclude Include="FrustumCulling.h" />
<ClInclude Include="GameProps.h" />
<ClInclude Include="GZipHeader.h" />
<ClInclude Include="IModel.h" />
<ClInclude Include="Intersection.h" />
<ClInclude Include="IO.h" />
<ClInclude Include="IsometricDrawer.h" />
@ -273,12 +274,14 @@
<ClCompile Include="FrustumCulling.c" />
<ClCompile Include="GameStructs.c" />
<ClCompile Include="GZipHeader.c" />
<ClCompile Include="IModel.c" />
<ClCompile Include="Intersection.c" />
<ClCompile Include="IsometricDrawer.c" />
<ClCompile Include="Lighting.c" />
<ClCompile Include="LiquidAnimations.c" />
<ClCompile Include="LocationUpdate.c" />
<ClCompile Include="MapRenderer.c" />
<ClCompile Include="ModelBuilder.c" />
<ClCompile Include="NormalBuilder.c" />
<ClCompile Include="PackedCol.c" />
<ClCompile Include="Funcs.c" />

View File

@ -142,6 +142,9 @@
<Filter Include="Header Files\Entities\Model">
<UniqueIdentifier>{1dd38dd7-06fa-492f-9226-9555516dd017}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Entities\Model">
<UniqueIdentifier>{d9fb5d8e-29d7-4774-abfb-d30b6ab766e7}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="NotchyGenerator.h">
@ -384,6 +387,9 @@
<ClInclude Include="ModelBuilder.h">
<Filter>Header Files\Entities\Model</Filter>
</ClInclude>
<ClInclude Include="IModel.h">
<Filter>Header Files\Entities\Model</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="NotchyGenerator.c">
@ -563,5 +569,11 @@
<ClCompile Include="AABB.c">
<Filter>Source Files\Math</Filter>
</ClCompile>
<ClCompile Include="ModelBuilder.c">
<Filter>Source Files\Entities\Model</Filter>
</ClCompile>
<ClCompile Include="IModel.c">
<Filter>Source Files\Entities\Model</Filter>
</ClCompile>
</ItemGroup>
</Project>

6
src/Client/IModel.c Normal file
View File

@ -0,0 +1,6 @@
#include "IModel.h"
void ModelVertex_Init(ModelVertex* vertex, Real32 x, Real32 y, Real32 z, UInt16 u, UInt16 v) {
vertex->X = x; vertex->Y = y; vertex->Z = z;
vertex->U = u; vertex->V = v;
}

29
src/Client/IModel.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef CS_MODEL_H
#define CS_MODEL_H
#include "Typedefs.h"
#include "Vectors.h"
/* Containts various structs and methods for an entity model.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
/* Describes a vertex within a model. */
typedef struct ModelVertex {
Real32 X, Y, Z;
UInt16 U, V;
} ModelVertex;
void ModelVertex_Init(ModelVertex* vertex, Real32 x, Real32 y, Real32 z, UInt16 u, UInt16 v);
/* Contains a set of quads and/or boxes that describe a 3D object as well as
the bounding boxes that contain the entire set of quads and/or boxes. */
typedef struct IModel {
/* Pointer to the raw vertices of the model.*/
ModelVertex* vertices;
/* Count of assigned vertices within the raw vertices array. */
Int32 index;
} IModel;
#endif

135
src/Client/ModelBuilder.c Normal file
View File

@ -0,0 +1,135 @@
#include "ModelBuilder.h"
#include "ExtMath.h"
void ModelPart_Init(ModelPart* part, Int32 offset, Int32 count, Real32 rotX, Real32 rotY, Real32 rotZ) {
part->Offset = offset; part->Count = count;
part->RotX = rotX; part->RotY = rotY; part->RotZ = rotZ;
}
void BoxDesc_TexOrigin(BoxDesc* desc, Int32 x, Int32 y) {
desc->TexX = x; desc->TexY = y;
}
void BoxDesc_SetBounds(BoxDesc* desc, Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2) {
desc->X1 = x1 / 16.0f; desc->X2 = x2 / 16.0f;
desc->Y1 = y1 / 16.0f; desc->Y2 = y2 / 16.0f;
desc->Z1 = z1 / 16.0f; desc->Z2 = z2 / 16.0f;
}
void BoxDesc_Expand(BoxDesc* desc, Real32 amount) {
amount /= 16.0f;
desc->X1 -= amount; desc->X2 += amount;
desc->Y1 -= amount; desc->Y2 += amount;
desc->Z1 -= amount; desc->Z2 += amount;
}
void BoxDesc_Scale(BoxDesc* desc, Real32 scale) {
desc->X1 *= scale; desc->X2 *= scale;
desc->Y1 *= scale; desc->Y2 *= scale;
desc->Z1 *= scale; desc->Z2 *= scale;
desc->RotX *= scale; desc->RotY *= scale; desc->RotZ *= scale;
}
void BoxDesc_RotOrigin(BoxDesc* desc, Int8 x, Int8 y, Int8 z) {
desc->RotX = (Real32)x / 16.0f;
desc->RotY = (Real32)y / 16.0f;
desc->RotZ = (Real32)z / 16.0f;
}
void BoxDesc_MirrorX(BoxDesc* desc) {
Real32 temp = desc->X1; desc->X1 = desc->X2; desc->X2 = temp;
}
#define BoxDesc_InitBox(desc)\
BoxDesc_TexOrigin(&desc, 0, 0);\
BoxDesc_RotOrigin(&desc, 0, 0, 0);\
BoxDesc_SetBounds(&desc, (Real32)x1, (Real32)y1, (Real32)z1, (Real32)x2, (Real32)y2, (Real32)z2);\
BoxDesc BoxDesc_Box(Int32 x1, Int32 y1, Int32 z1, Int32 x2, Int32 y2, Int32 z2) {
BoxDesc desc;
BoxDesc_InitBox(desc)
desc.SidesW = Math_AbsI(z2 - z1);
desc.BodyW = Math_AbsI(x2 - x1);
desc.BodyH = Math_AbsI(y2 - y1);
return desc;
}
BoxDesc BoxDesc_RotatedBox(Int32 x1, Int32 y1, Int32 z1, Int32 x2, Int32 y2, Int32 z2) {
BoxDesc desc;
BoxDesc_InitBox(desc)
desc.SidesW = Math_AbsI(y2 - y1);
desc.BodyW = Math_AbsI(x2 - x1);
desc.BodyH = Math_AbsI(z2 - z1);
return desc;
}
ModelPart BoxDesc_BuildBox(IModel* m, BoxDesc* desc) {
Int32 sidesW = desc->SidesW, bodyW = desc->BodyW, bodyH = desc->BodyH;
Real32 x1 = desc->X1, y1 = desc->Y1, z1 = desc->Z1;
Real32 x2 = desc->X2, y2 = desc->Y2, z2 = desc->Z2;
Int32 x = desc->TexX, y = desc->TexY;
BoxDesc_YQuad(m, x + sidesW, y, bodyW, sidesW, x2, x1, z2, z1, y2); /* top */
BoxDesc_YQuad(m, x + sidesW + bodyW, y, bodyW, sidesW, x2, x1, z2, z1, y1); /* bottom */
BoxDesc_ZQuad(m, x + sidesW, y + sidesW, bodyW, bodyH, x2, x1, y1, y2, z1); /* front */
BoxDesc_ZQuad(m, x + sidesW + bodyW + sidesW, y + sidesW, bodyW, bodyH, x1, x2, y1, y2, z2); /* back */
BoxDesc_XQuad(m, x, y + sidesW, sidesW, bodyH, z2, z1, y1, y2, x2); /* left */
BoxDesc_XQuad(m, x + sidesW + bodyW, y + sidesW, sidesW, bodyH, z1, z2, y1, y2, x1); /* right */
ModelPart part;
ModelPart_Init(&part, m->index - 6 * 4, 6 * 4, desc->RotX, desc->RotY, desc->RotZ);
return part;
}
ModelPart BoxDesc_BuildRotatedBox(IModel* m, BoxDesc* desc) {
Int32 sidesW = desc->SidesW, bodyW = desc->BodyW, bodyH = desc->BodyH;
Real32 x1 = desc->X1, y1 = desc->Y1, z1 = desc->Z1;
Real32 x2 = desc->X2, y2 = desc->Y2, z2 = desc->Z2;
Int32 x = desc->TexX, y = desc->TexY;
BoxDesc_YQuad(m, x + sidesW + bodyW + sidesW, y + sidesW, bodyW, bodyH, x1, x2, z1, z2, y2); /* top */
BoxDesc_YQuad(m, x + sidesW, y + sidesW, bodyW, bodyH, x2, x1, z1, z2, y1); /* bottom */
BoxDesc_ZQuad(m, x + sidesW, y, bodyW, sidesW, x2, x1, y1, y2, z1); /* front */
BoxDesc_ZQuad(m, x + sidesW + bodyW, y, bodyW, sidesW, x1, x2, y2, y1, z2); /* back */
BoxDesc_XQuad(m, x, y + sidesW, sidesW, bodyH, y2, y1, z2, z1, x2); /* left */
BoxDesc_XQuad(m, x + sidesW + bodyW, y + sidesW, sidesW, bodyH, y1, y2, z2, z1, x1); /* right */
/* rotate left and right 90 degrees */
Int32 i;
for (i = m->index - 8; i < m->index; i++) {
ModelVertex vertex = m->vertices[i];
Real32 z = vertex.Z; vertex.Z = vertex.Y; vertex.Y = z;
m->vertices[i] = vertex;
}
ModelPart part;
ModelPart_Init(&part, m->index - 6 * 4, 6 * 4, desc->RotX, desc->RotY, desc->RotZ);
return part;
}
static void BoxDesc_XQuad(IModel* m, Int32 texX, Int32 texY, Int32 texWidth, Int32 texHeight,
Real32 z1, Real32 z2, Real32 y1, Real32 y2, Real32 x) {
ModelVertex_Init(&m->vertices[m->index], x, y1, z1, texX, texY + texHeight); m->index++;
ModelVertex_Init(&m->vertices[m->index], x, y2, z1, texX, texY); m->index++;
ModelVertex_Init(&m->vertices[m->index], x, y2, z2, texX + texWidth, texY); m->index++;
ModelVertex_Init(&m->vertices[m->index], x, y1, z2, texX + texWidth, texY + texHeight); m->index++;
}
static void BoxDesc_YQuad(IModel* m, Int32 texX, Int32 texY, Int32 texWidth, Int32 texHeight,
Real32 x1, Real32 x2, Real32 z1, Real32 z2, Real32 y) {
ModelVertex_Init(&m->vertices[m->index], x1, y, z2, texX, texY + texHeight); m->index++;
ModelVertex_Init(&m->vertices[m->index], x1, y, z1, texX, texY); m->index++;
ModelVertex_Init(&m->vertices[m->index], x2, y, z1, texX + texWidth, texY); m->index++;
ModelVertex_Init(&m->vertices[m->index], x2, y, z2, texX + texWidth, texY + texHeight); m->index++;
}
static void BoxDesc_ZQuad(IModel* m, Int32 texX, Int32 texY, Int32 texWidth, Int32 texHeight,
Real32 x1, Real32 x2, Real32 y1, Real32 y2, Real32 z) {
ModelVertex_Init(&m->vertices[m->index], x1, y1, z, texX, texY + texHeight); m->index++;
ModelVertex_Init(&m->vertices[m->index], x1, y2, z, texX, texY); m->index++;
ModelVertex_Init(&m->vertices[m->index], x2, y2, z, texX + texWidth, texY); m->index++;
ModelVertex_Init(&m->vertices[m->index], x2, y1, z, texX + texWidth, texY + texHeight); m->index++;
}

View File

@ -2,7 +2,8 @@
#define CS_MODELBUILDER_H
#include "Typedefs.h"
#include "Vectors.h"
/* Containts various structs and methods that assist with building an entity model.
#include "IModel.h"
/* Contains various structs and methods that assist with building an entity model.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
@ -19,11 +20,21 @@ typedef struct BoxDesc {
} BoxDesc;
/* Describes the starting index of this part within a model's array of vertices,
and the number of vertices following the starting index that this part uses. */
typedef struct ModelPart {
Int32 Offset, Count;
Real32 RotX, RotY, RotZ;
} ModelPart;
void ModelPart_Init(ModelPart* part, Int32 offset, Int32 count, Real32 rotX, Real32 rotY, Real32 rotZ);
/* Sets the texture origin for this part within the texture atlas. */
void BoxDesc_TexOrigin(BoxDesc* desc, Int32 x, Int32 y);
/* Sets the the two corners of this box, in pixel coordinates. */
void BoxDesc_SetModelBounds(BoxDesc* desc, Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2);
void BoxDesc_SetBounds(BoxDesc* desc, Real32 x1, Real32 y1, Real32 z1, Real32 x2, Real32 y2, Real32 z2);
/* Expands the corners of this box outwards by the given amount in pixel coordinates. */
void BoxDesc_Expand(BoxDesc* desc, Real32 amount);
@ -75,7 +86,7 @@ let SW = sides width, BW = body width, BH = body height
|H--------tex---------H|H--------tex---------H|H--------tex---------H|H--------tex---------H|
|----------SW----------|----------BW----------|----------BW----------|----------------------|
********************************************************************************************* */
ModelPart BoxDesc_BuildRotatedBox(IModel* m, BoxDesc desc);
ModelPart BoxDesc_BuildRotatedBox(IModel* m, BoxDesc* desc);
static void BoxDesc_XQuad(IModel* m, Int32 texX, Int32 texY, Int32 texWidth, Int32 texHeight,