added animation support to obj

This commit is contained in:
Sandro Sobczyński
2020-10-28 20:42:17 +01:00
parent abda2fe3fa
commit 9e00ef3634
12 changed files with 242 additions and 119 deletions
+35 -10
View File
@@ -78,16 +78,36 @@ void Mesh::setDff(Vector3 &t_initPos, DffModel *t_dffModel, MeshSpec *t_spec)
isDffLoaded = true;
}
void Mesh::loadObj(char *t_subfolder, char *t_objFile, Vector3 &t_initPos, float t_scale)
void Mesh::loadObj(char *t_subfolder, char *t_objFile, Vector3 &t_initPos, float t_scale, u16 framesAmount)
{
createSpecIfNotCreated();
ObjLoader loader = ObjLoader();
obj = new ObjModel(t_objFile);
char *objPath = String::createConcatenated(t_subfolder, t_objFile);
loader.load(obj, objPath, t_scale);
delete[] objPath;
obj->frameCount = framesAmount;
obj->frames = new Frame[framesAmount];
char *part1 = String::createConcatenated(t_subfolder, t_objFile); // "folder/object"
char *part2 = String::createConcatenated(part1, "_"); // "folder/object_"
delete[] part1;
for (u16 i = 0; i < framesAmount; i++)
{
char *part3 = String::createU32ToString(i + 1); // 0 -> "1"
char *part4 = String::createWithLeadingZeros(part3); // "000001"
char *part5 = String::createConcatenated(part2, part4); // "folder/object_000001"
char *finalPath = String::createConcatenated(part5, ".obj"); // "folder/object_000001.obj"
loader.load(&obj->frames[i], finalPath, t_scale);
delete[] part3;
delete[] part4;
delete[] part5;
delete[] finalPath;
}
delete[] part2;
position = t_initPos;
setVerticesReference(obj->getFacesCount(), obj->vertices);
setVerticesReference(obj->getFacesCount(), obj->frames[0].vertices);
setDefaultColor();
isObjLoaded = true;
loadTextures(t_subfolder, ".bmp");
@@ -100,7 +120,7 @@ void Mesh::setObj(Vector3 &t_initPos, ObjModel *t_objModel, MeshSpec *t_spec)
spec = t_spec;
isSpecInitialized = true;
obj = t_objModel;
setVerticesReference(obj->getFacesCount(), obj->vertices);
setVerticesReference(obj->getFacesCount(), obj->frames[0].vertices);
setDefaultColor();
isObjLoaded = true;
}
@@ -159,10 +179,10 @@ void Mesh::loadTextures(char *t_subfolder, char *t_extension)
BmpLoader bmpLoader = BmpLoader();
if (isObjLoaded)
{
spec->textures = new Texture[obj->materialsCount];
for (u8 i = 0; i < obj->materialsCount; i++)
spec->textures = new Texture[obj->frames[0].materialsCount];
for (u8 i = 0; i < obj->frames[0].materialsCount; i++)
{
bmpLoader.load(spec->textures[i], t_subfolder, obj->materials[i].materialName, t_extension);
bmpLoader.load(spec->textures[i], t_subfolder, obj->frames[0].materials[i].materialName, t_extension);
setDefaultWrapSettings(spec->textures[i].wrapSettings);
}
}
@@ -265,8 +285,13 @@ void Mesh::playAnimation(u32 t_startFrame, u32 t_endFrame)
md2->animState.startFrame = t_startFrame;
md2->animState.endFrame = t_endFrame;
}
else if (isObjLoaded == 1)
{
obj->animState.startFrame = t_startFrame;
obj->animState.endFrame = t_endFrame;
}
else
PRINT_ERR("Animation is only supported in MD2 format!");
PRINT_ERR("Animation is only supported in MD2/OBJ format!");
}
/** Returns next farthest vertex of 3D object
+77 -42
View File
@@ -19,6 +19,13 @@
ObjModel::ObjModel(char *t_objFile)
{
animState.startFrame = 0;
animState.endFrame = 0;
animState.interpolation = 0.0F;
animState.animType = 0;
animState.currentFrame = 0;
animState.nextFrame = 0;
animState.speed = 0.1F;
filename = String::createWithoutExtension(t_objFile);
}
@@ -26,17 +33,18 @@ ObjModel::~ObjModel()
{
if (isMemoryAllocated == true)
{
delete[] vertices;
delete[] coordinates;
delete[] normals;
for (u16 i = 0; i < materialsCount; i++)
{
delete[] materials[i].verticeFaces;
delete[] materials[i].coordinateFaces;
delete[] materials[i].normalFaces;
delete[] materials[i].materialName;
}
delete[] materials;
// TODO !!!!
// delete[] vertices;
// delete[] coordinates;
// delete[] normals;
// for (u16 i = 0; i < materialsCount; i++)
// {
// delete[] materials[i].verticeFaces;
// delete[] materials[i].coordinateFaces;
// delete[] materials[i].normalFaces;
// delete[] materials[i].materialName;
// }
// delete[] materials;
}
}
@@ -46,48 +54,75 @@ ObjModel::~ObjModel()
u32 ObjModel::getFacesCount()
{
u32 result = 0;
for (u16 i = 0; i < materialsCount; i++)
result += materials[i].facesCount;
u32 result = 0; // TODO
for (u16 i = 0; i < frames[0].materialsCount; i++)
result += frames[0].materials[i].facesCount;
return result;
}
u32 ObjModel::getDrawData(u32 t_materialIndex, VECTOR *o_vertices, VECTOR *o_normals, VECTOR *o_coordinates, VECTOR *o_colors, Vector3 &t_cameraPos, float t_scale, u8 t_shouldBeBackfaceCulled)
{
u32 addedFaces = 0;
for (u32 j = 0; j < materials[t_materialIndex].facesCount; j += 3)
if (!t_shouldBeBackfaceCulled || Vector3::shouldBeBackfaceCulled(
&t_cameraPos,
&vertices[materials[t_materialIndex].verticeFaces[j]],
&vertices[materials[t_materialIndex].verticeFaces[j + 1]],
&vertices[materials[t_materialIndex].verticeFaces[j + 2]]) == 0)
animState.interpolation += animState.speed; // TODO move it out
if (animState.interpolation >= 1.0F)
{
animState.interpolation = 0.0F;
animState.currentFrame = animState.nextFrame;
if (++animState.nextFrame > animState.endFrame)
animState.nextFrame = animState.startFrame;
}
for (u32 j = 0; j < frames[animState.currentFrame].materials[t_materialIndex].facesCount; j += 3)
{
for (u32 iVert = 0; iVert < 3; iVert++)
{
fillNextFace(o_vertices, o_normals, o_coordinates, o_colors, t_materialIndex, j, addedFaces++);
fillNextFace(o_vertices, o_normals, o_coordinates, o_colors, t_materialIndex, j + 1, addedFaces++);
fillNextFace(o_vertices, o_normals, o_coordinates, o_colors, t_materialIndex, j + 2, addedFaces++);
const ObjMaterial CURR_MAT = frames[animState.currentFrame].materials[t_materialIndex];
const Vector3 CURR_VERT = frames[animState.currentFrame].vertices[CURR_MAT.verticeFaces[j + iVert]];
if (animState.startFrame == animState.endFrame)
{
calc3Vectors[iVert].x = CURR_VERT.x * t_scale;
calc3Vectors[iVert].y = CURR_VERT.y * t_scale;
calc3Vectors[iVert].z = CURR_VERT.z * t_scale;
}
else
{
const Vector3 NEXT_VERT = frames[animState.nextFrame].vertices[CURR_MAT.verticeFaces[j + iVert]];
calcVector.setByLerp(CURR_VERT, NEXT_VERT, animState.interpolation);
calc3Vectors[iVert].x = calcVector.x * t_scale;
calc3Vectors[iVert].y = calcVector.y * t_scale;
calc3Vectors[iVert].z = calcVector.z * t_scale;
}
}
if (!t_shouldBeBackfaceCulled || Vector3::shouldBeBackfaceCulled(&t_cameraPos, &calc3Vectors[2], &calc3Vectors[1], &calc3Vectors[0]) == 0)
for (u32 iVert = 0; iVert < 3; iVert++)
{
const u32 CURR_FRAME = animState.currentFrame;
o_vertices[addedFaces][0] = calc3Vectors[iVert].x;
o_vertices[addedFaces][1] = calc3Vectors[iVert].y;
o_vertices[addedFaces][2] = calc3Vectors[iVert].z;
o_vertices[addedFaces][3] = 1.0F;
o_normals[addedFaces][0] = frames[CURR_FRAME].normals[frames[CURR_FRAME].materials[t_materialIndex].normalFaces[j]].x;
o_normals[addedFaces][1] = frames[CURR_FRAME].normals[frames[CURR_FRAME].materials[t_materialIndex].normalFaces[j]].y;
o_normals[addedFaces][2] = frames[CURR_FRAME].normals[frames[CURR_FRAME].materials[t_materialIndex].normalFaces[j]].z;
o_normals[addedFaces][3] = 1.0F;
o_coordinates[addedFaces][0] = frames[CURR_FRAME].coordinates[frames[CURR_FRAME].materials[t_materialIndex].coordinateFaces[j]].x;
o_coordinates[addedFaces][1] = frames[CURR_FRAME].coordinates[frames[CURR_FRAME].materials[t_materialIndex].coordinateFaces[j]].y;
o_coordinates[addedFaces][2] = 1.0F;
o_coordinates[addedFaces][3] = 1.0F;
o_colors[addedFaces][0] = 1.0F;
o_colors[addedFaces][1] = 1.0F;
o_colors[addedFaces][2] = 1.0F;
o_colors[addedFaces++][3] = 1.0F;
}
// fillNextFace(o_vertices, o_normals, o_coordinates, o_colors, t_materialIndex, j, addedFaces++);
}
return addedFaces;
}
void ObjModel::fillNextFace(VECTOR *o_vertices, VECTOR *o_normals, VECTOR *o_coordinates, VECTOR *o_colors, u32 t_materialI, u32 t_getI, u32 t_setI)
{
o_vertices[t_setI][0] = vertices[materials[t_materialI].verticeFaces[t_getI]].x;
o_vertices[t_setI][1] = vertices[materials[t_materialI].verticeFaces[t_getI]].y;
o_vertices[t_setI][2] = vertices[materials[t_materialI].verticeFaces[t_getI]].z;
o_vertices[t_setI][3] = 1.0F;
o_normals[t_setI][0] = normals[materials[t_materialI].normalFaces[t_getI]].x;
o_normals[t_setI][1] = normals[materials[t_materialI].normalFaces[t_getI]].y;
o_normals[t_setI][2] = normals[materials[t_materialI].normalFaces[t_getI]].z;
o_normals[t_setI][3] = 1.0F;
o_coordinates[t_setI][0] = coordinates[materials[t_materialI].coordinateFaces[t_getI]].x;
o_coordinates[t_setI][1] = coordinates[materials[t_materialI].coordinateFaces[t_getI]].y;
o_coordinates[t_setI][2] = 1.0F;
o_coordinates[t_setI][3] = 1.0F;
o_colors[t_setI][0] = 1.0F;
o_colors[t_setI][1] = 1.0F;
o_colors[t_setI][2] = 1.0F;
o_colors[t_setI][3] = 1.0F;
}