mesh patch 1

This commit is contained in:
h4570
2022-08-09 23:12:09 +02:00
parent 6b45629595
commit 2dad96d396
33 changed files with 252 additions and 661 deletions
+6 -3
View File
@@ -1,14 +1,17 @@
------------ Tyra's v2.0 roadmap to publish on GitHub ------------
- [General] builder2
- [General] Znalezc problem w loaderze/ach
- [General] Assert czy ramki w obj maja taka sama ilosc danych
- [General] Clip glitch na tutorial01
- [General] Rename builder2
- [Obj] soldier_000001
- [General] vec3/vec4/m4x4 functions from ms
- [General] std::vector in mesh instead of array**
- [General] Allow to edit all data from mesh/texture
- [General] odpalic de_dust2, doszlifowac guard band
- [General] manycolor -> lightmap
- [General] rename invertT -> invertY
- [General] ładować ambient i wrzucać do material. Zmienic nazwe na ambient
- [General] wszystkie new M4x4 i = M4x4 na M4x4::Identity
- [General] wyeksportowac z blendera warianty, color, tex, tex+normal, color+normal i sprawdzic
- [General] USB test
- [General] Tyra version, render it on start
@@ -41,7 +44,7 @@ because Mesh rendering uses only core.render()
- [General] Credits: clipping, obj loader
------------ Github issues for Tyra v2 ------------
- [General] Async file loading
- [md2] refactor
- [3D] Add drawLine(x, y , color, size)
- [2D] Fixed font support
- [3D] Add drawBBox(x, y , color, size)
@@ -1,37 +0,0 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "./mesh_builder_material_data.hpp"
#include "./mesh_builder_frame_data.hpp"
namespace Tyra {
class MeshBuilderData {
public:
MeshBuilderData();
~MeshBuilderData();
MeshBuilderFrameData** frames;
u32 framesCount;
MeshBuilderMaterialData** materials;
u32 materialsCount;
bool textureCoordsEnabled, normalsEnabled, manyColorsEnabled;
void allocateFrames(const u32& count);
void allocateMaterials(const u32& count);
void allocate(const u32& framesCount, const u32& materialsCount);
};
} // namespace Tyra
@@ -1,35 +0,0 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tamtypes.h>
#include "math/vec4.hpp"
#include "renderer/models/color.hpp"
namespace Tyra {
class MeshBuilderFrameData {
public:
MeshBuilderFrameData();
~MeshBuilderFrameData();
Vec4 *vertices, *normals, *textureCoords;
Color* colors;
u32 verticesCount, textureCoordsCount, normalsCount, colorsCount;
void allocateTextureCoords(const u32& count);
void allocateVertices(const u32& count);
void allocateNormals(const u32& count);
void allocateColors(const u32& count);
};
} // namespace Tyra
@@ -1,31 +0,0 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tamtypes.h>
#include <string>
namespace Tyra {
class MeshBuilderMaterialData {
public:
MeshBuilderMaterialData();
~MeshBuilderMaterialData();
std::string name;
u32 *vertexFaces, *textureCoordFaces, *normalFaces, *colorFaces;
u32 count;
void allocateFaces(const u32& count);
};
} // namespace Tyra
@@ -11,7 +11,7 @@
#pragma once
#include "../../loader.hpp"
#include "../builder/mesh_builder_data.hpp"
#include "../builder2/mesh_builder2_data.hpp"
#include <string>
namespace Tyra {
@@ -22,10 +22,10 @@ class MD2Loader : public Loader {
MD2Loader();
~MD2Loader();
MeshBuilderData* load(const char* fullpath, const float& scale,
MeshBuilder2Data* load(const char* fullpath, const float& scale,
const bool& invertT);
inline MeshBuilderData* load(const std::string& fullpath, const float& scale,
inline MeshBuilder2Data* load(const std::string& fullpath, const float& scale,
const bool& invertT) {
return load(fullpath.c_str(), scale, invertT);
}
@@ -34,11 +34,17 @@ class ObjLoader : public Loader {
}
private:
void setInitialData(MeshBuilder2Data* output, const tinyobj::attrib_t& attrib,
void addOutputMaterialsAndFrames(
MeshBuilder2Data* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials,
const u16& framesCount);
void scan(MeshBuilder2Data* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials,
const u16& frameIndex);
void importFrame(MeshBuilder2Data* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials,
@@ -10,7 +10,6 @@
#pragma once
#include "loaders/3d/builder/mesh_builder_data.hpp"
#include "../mesh_frame.hpp"
#include "../mesh_material_frame.hpp"
#include "./dynamic_mesh_anim_state.hpp"
@@ -20,7 +19,6 @@ namespace Tyra {
class DynamicMesh : public Mesh {
public:
explicit DynamicMesh(const MeshBuilderData& data);
explicit DynamicMesh(const MeshBuilder2Data& data);
explicit DynamicMesh(const DynamicMesh& mesh);
~DynamicMesh();
-1
View File
@@ -19,7 +19,6 @@ namespace Tyra {
class Mesh {
public:
explicit Mesh(const MeshBuilderData& data);
explicit Mesh(const MeshBuilder2Data& data);
explicit Mesh(const Mesh& mesh);
~Mesh();
@@ -11,7 +11,6 @@
#pragma once
#include "./mesh_material.hpp"
#include "loaders/3d/builder/mesh_builder_data.hpp"
#include "loaders/3d/builder2/mesh_builder2_data.hpp"
#include "renderer/3d/bbox/bbox.hpp"
@@ -19,7 +18,6 @@ namespace Tyra {
class MeshFrame {
public:
explicit MeshFrame(const MeshBuilderData& data, const u32& index);
explicit MeshFrame(const MeshBuilder2Data& data, const u32& index);
explicit MeshFrame(const MeshFrame& frame);
~MeshFrame();
@@ -11,15 +11,13 @@
#pragma once
#include "debug/debug.hpp"
#include "loaders/3d/builder/mesh_builder_data.hpp"
#include "loaders/3d/builder2/mesh_builder2_data.hpp"
#include "./mesh_material_frame.hpp"
#include "loaders/3d/builder2/mesh_builder2_data.hpp"
namespace Tyra {
class MeshMaterial {
public:
explicit MeshMaterial(const MeshBuilderData& data, const u32& materialIndex);
explicit MeshMaterial(const MeshBuilder2Data& data, const u32& materialIndex);
explicit MeshMaterial(const MeshMaterial& material);
~MeshMaterial();
@@ -10,7 +10,6 @@
#pragma once
#include "loaders/3d/builder/mesh_builder_data.hpp"
#include "loaders/3d/builder2/mesh_builder2_data.hpp"
#include "./renderer/3d/bbox/bbox.hpp"
@@ -18,8 +17,6 @@ namespace Tyra {
class MeshMaterialFrame {
public:
explicit MeshMaterialFrame(const MeshBuilderData& data, const u32& frameIndex,
const u32& materialIndex);
explicit MeshMaterialFrame(const MeshBuilder2Data& data,
const u32& frameIndex, const u32& materialIndex);
explicit MeshMaterialFrame(const MeshMaterialFrame& frame);
@@ -41,15 +38,6 @@ class MeshMaterialFrame {
std::string getPrint(const char* name = nullptr) const;
private:
void allocateVertices(const MeshBuilderData& data, const u32& frameIndex,
const u32& materialIndex);
void allocateTextureCoords(const MeshBuilderData& data, const u32& frameIndex,
const u32& materialIndex);
void allocateNormals(const MeshBuilderData& data, const u32& frameIndex,
const u32& materialIndex);
void allocateColors(const MeshBuilderData& data, const u32& frameIndex,
const u32& materialIndex);
BBox* bbox;
u8 _isMother;
@@ -18,7 +18,6 @@ namespace Tyra {
class StaticMesh : public Mesh {
public:
StaticMesh(const MeshBuilderData& data);
StaticMesh(const MeshBuilder2Data& data);
StaticMesh(const StaticMesh& mesh);
~StaticMesh();
@@ -50,6 +50,7 @@ class DynPipRenderer {
prim_t* prim;
lod_t* lod;
u16 packetSize;
packet2_t* packets[2];
packet2_t* programsPacket;
@@ -85,7 +85,7 @@ class StaPipQBufferRenderer {
static const u16 buffersCount;
StaPipVU1Program* getProgramByName(const StaPipProgramName& name);
void addBufferDataToPacket(StaPipQBuffer** buffers, const u32& count);
void addBuffersDataToPacket(const u32& from, const u32& to);
void sendPacket();
StaPipVU1Program* getAsIsProgramByBag(const StaPipBag* bag);
StaPipVU1Program* getCullProgramByType(const StaPipProgramType& programType);
@@ -1,69 +0,0 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "loaders/3d/builder/mesh_builder_data.hpp"
#include "debug/debug.hpp"
namespace Tyra {
MeshBuilderData::MeshBuilderData() {
normalsEnabled = false;
textureCoordsEnabled = false;
manyColorsEnabled = false;
materials = nullptr;
frames = nullptr;
}
MeshBuilderData::~MeshBuilderData() {
if (frames) {
for (u32 i = 0; i < framesCount; i++) {
delete frames[i];
}
delete[] frames;
}
if (materials) {
for (u32 i = 0; i < materialsCount; i++) {
delete materials[i];
}
delete[] materials;
}
}
void MeshBuilderData::allocate(const u32& framesCount,
const u32& materialsCount) {
allocateFrames(framesCount);
allocateMaterials(materialsCount);
}
void MeshBuilderData::allocateFrames(const u32& count) {
this->framesCount = count;
TYRA_ASSERT(frames == nullptr, "Frames are already allocated");
frames = new MeshBuilderFrameData*[count];
for (u32 i = 0; i < count; i++) {
frames[i] = new MeshBuilderFrameData();
}
}
void MeshBuilderData::allocateMaterials(const u32& count) {
this->materialsCount = count;
TYRA_ASSERT(materials == nullptr, "Materials are already allocated");
materials = new MeshBuilderMaterialData*[count];
for (u32 i = 0; i < count; i++) {
materials[i] = new MeshBuilderMaterialData();
}
}
} // namespace Tyra
@@ -1,71 +0,0 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "loaders/3d/builder/mesh_builder_frame_data.hpp"
#include "debug/debug.hpp"
namespace Tyra {
MeshBuilderFrameData::MeshBuilderFrameData() {
vertices = nullptr;
normals = nullptr;
textureCoords = nullptr;
colors = nullptr;
verticesCount = 0;
textureCoordsCount = 0;
normalsCount = 0;
colorsCount = 0;
}
MeshBuilderFrameData::~MeshBuilderFrameData() {
if (vertices) {
delete[] vertices;
}
if (normals) {
delete[] normals;
}
if (textureCoords) {
delete[] textureCoords;
}
if (colors) {
delete[] colors;
}
}
void MeshBuilderFrameData::allocateTextureCoords(const u32& count) {
if (count == 0) return;
TYRA_ASSERT(textureCoords == nullptr, "Texture coords are already allocated");
textureCoordsCount = count;
textureCoords = new Vec4[count];
}
void MeshBuilderFrameData::allocateVertices(const u32& count) {
if (count == 0) return;
TYRA_ASSERT(vertices == nullptr, "Vertices are already allocated");
verticesCount = count;
vertices = new Vec4[count];
}
void MeshBuilderFrameData::allocateNormals(const u32& count) {
if (count == 0) return;
TYRA_ASSERT(normals == nullptr, "Normals are already allocated");
normalsCount = count;
normals = new Vec4[count];
}
void MeshBuilderFrameData::allocateColors(const u32& count) {
if (count == 0) return;
TYRA_ASSERT(colors == nullptr, "Colors are already allocated");
colorsCount = count;
colors = new Color[count];
}
} // namespace Tyra
@@ -1,52 +0,0 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "loaders/3d/builder/mesh_builder_material_data.hpp"
#include "debug/debug.hpp"
namespace Tyra {
MeshBuilderMaterialData::MeshBuilderMaterialData() {
vertexFaces = nullptr;
textureCoordFaces = nullptr;
normalFaces = nullptr;
colorFaces = nullptr;
name = "";
count = 0;
}
MeshBuilderMaterialData::~MeshBuilderMaterialData() {
if (vertexFaces) {
delete[] vertexFaces;
}
if (textureCoordFaces) {
delete[] textureCoordFaces;
}
if (normalFaces) {
delete[] normalFaces;
}
if (colorFaces) {
delete[] colorFaces;
}
}
void MeshBuilderMaterialData::allocateFaces(const u32& t_count) {
TYRA_ASSERT(vertexFaces == nullptr && textureCoordFaces == nullptr &&
normalFaces == nullptr && colorFaces == nullptr,
"Faces are already allocated");
vertexFaces = new u32[t_count];
textureCoordFaces = new u32[t_count];
normalFaces = new u32[t_count];
colorFaces = new u32[t_count];
count = t_count;
}
} // namespace Tyra
+63 -34
View File
@@ -8,13 +8,12 @@
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "loaders/3d/md2_loader/md2_loader.hpp"
#include <stdio.h>
#include <string>
#include "debug/debug.hpp"
#include "loaders/3d/builder/mesh_builder_data.hpp"
#include "loaders/3d/md2_loader/anorms.hpp"
#include "loaders/loader.hpp"
#include "loaders/3d/md2_loader/md2_loader.hpp"
namespace Tyra {
@@ -75,7 +74,7 @@ MD2Loader::MD2Loader() {}
MD2Loader::~MD2Loader() {}
MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale,
MeshBuilder2Data* MD2Loader::load(const char* fullpath, const float& scale,
const bool& invertT) {
std::string path = fullpath;
TYRA_ASSERT(!path.empty(), "Provided path is empty!");
@@ -111,47 +110,58 @@ MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale,
fclose(file);
auto result = new MeshBuilderData();
result->allocate(framesCount, 1);
auto result = new MeshBuilder2Data();
auto* material = new MeshBuilder2MaterialData();
material->name = getFilenameWithoutExtension(filename);
result->materials.push_back(material);
result->normalsEnabled = true;
result->textureCoordsEnabled = true;
result->manyColorsEnabled = false;
result->lightMapEnabled = false;
result->materials[0]->allocateFaces(trianglesCount * 3);
result->materials[0]->name = getFilenameWithoutExtension(filename);
Vec4** tempVertices = new Vec4*[framesCount];
Vec4** tempNormals = new Vec4*[framesCount];
Vec4** tempTexCoords = new Vec4*[framesCount];
for (u32 i = 0; i < framesCount; i++) {
auto* outputFrame = new MeshBuilder2MaterialFrameData();
material->frames.push_back(outputFrame);
tempVertices[i] = new Vec4[vertexCount];
tempNormals[i] = new Vec4[vertexCount];
tempTexCoords[i] = new Vec4[stsCount];
}
frame_t* frame;
Vec4 temp(0.0F, 0.0F, 0.0F, 1.0F);
for (u32 j = 0; j < framesCount; j++) {
result->frames[j]->allocateVertices(vertexCount);
result->frames[j]->allocateNormals(vertexCount);
result->frames[j]->allocateTextureCoords(stsCount);
frame = reinterpret_cast<frame_t*>(&framesBuffer[header.framesize * j]);
for (u32 frameIndex = 0; frameIndex < framesCount; frameIndex++) {
auto* frame = reinterpret_cast<frame_t*>(
&framesBuffer[header.framesize * frameIndex]);
for (u32 i = 0; i < vertexCount; i++) {
temp.set(
((frame->verts[i].v[0] * frame->scale[0]) + frame->translate[0]) *
for (u32 vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) {
temp.set(((frame->verts[vertexIndex].v[0] * frame->scale[0]) +
frame->translate[0]) *
scale,
((frame->verts[i].v[1] * frame->scale[1]) + frame->translate[1]) *
((frame->verts[vertexIndex].v[1] * frame->scale[1]) +
frame->translate[1]) *
scale,
((frame->verts[i].v[2] * frame->scale[2]) + frame->translate[2]) *
((frame->verts[vertexIndex].v[2] * frame->scale[2]) +
frame->translate[2]) *
scale);
result->frames[j]->vertices[i].set(temp);
tempVertices[frameIndex][vertexIndex].set(temp);
temp.set(ANORMS[frame->verts[i].lightnormalindex][0],
ANORMS[frame->verts[i].lightnormalindex][1],
ANORMS[frame->verts[i].lightnormalindex][2]);
temp.set(ANORMS[frame->verts[vertexIndex].lightnormalindex][0],
ANORMS[frame->verts[vertexIndex].lightnormalindex][1],
ANORMS[frame->verts[vertexIndex].lightnormalindex][2]);
result->frames[j]->normals[i].set(temp);
tempNormals[frameIndex][vertexIndex].set(temp);
}
}
texCoord_t* texCoord;
for (u32 i = 0; i < stsCount; i++) {
texCoord =
auto* texCoord =
reinterpret_cast<texCoord_t*>(&stsBuffer[sizeof(texCoord_t) * i]);
temp.set(static_cast<float>(texCoord->s) / header.skinwidth,
@@ -159,8 +169,14 @@ MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale,
if (invertT) temp.y = 1.0F - temp.y;
for (u32 j = 0; j < framesCount; j++)
result->frames[j]->textureCoords[i].set(temp);
for (u32 j = 0; j < framesCount; j++) tempTexCoords[j][i].set(temp);
}
for (u32 x = 0; x < framesCount; x++) {
material->frames[x]->count = trianglesCount * 3;
material->frames[x]->vertices = new Vec4[trianglesCount * 3];
material->frames[x]->normals = new Vec4[trianglesCount * 3];
material->frames[x]->textureCoords = new Vec4[trianglesCount * 3];
}
triangle_t* triangle;
@@ -168,18 +184,31 @@ MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale,
triangle =
reinterpret_cast<triangle_t*>(&trianglesBuffer[sizeof(triangle_t) * i]);
for (u8 j = 0; j < 3; j++) {
for (u32 x = 0; x < framesCount; x++) {
result->materials[0]->vertexFaces[(i * 3) + j] = triangle->index_xyz[j];
auto* workFrame = material->frames[x];
result->materials[0]->textureCoordFaces[(i * 3) + j] =
triangle->index_st[j];
for (u8 j = 0; j < 3; j++) {
workFrame->vertices[i * 3 + j] =
tempVertices[x][triangle->index_xyz[j]];
result->materials[0]->normalFaces[(i * 3) + j] = triangle->index_xyz[j];
workFrame->normals[i * 3 + j] = tempNormals[x][triangle->index_xyz[j]];
workFrame->textureCoords[i * 3 + j] =
tempTexCoords[x][triangle->index_st[j]];
}
}
}
for (u32 i = 0; i < framesCount; i++) {
delete[] tempVertices[i];
delete[] tempNormals[i];
delete[] tempTexCoords[i];
}
delete[] tempVertices;
delete[] tempNormals;
delete[] tempTexCoords;
delete[] framesBuffer;
delete[] stsBuffer;
delete[] trianglesBuffer;
+81 -45
View File
@@ -72,9 +72,11 @@ MeshBuilder2Data* ObjLoader::load(const char* fullpath, const u16& count,
"mtlib in obj file");
if (i == 1) {
setInitialData(result, attrib, shapes, materials, count);
addOutputMaterialsAndFrames(result, attrib, shapes, materials, count);
}
scan(result, attrib, shapes, materials, i - 1);
importFrame(result, attrib, shapes, materials, i - 1, scale, invertY,
count);
}
@@ -82,7 +84,7 @@ MeshBuilder2Data* ObjLoader::load(const char* fullpath, const u16& count,
return result;
}
void ObjLoader::setInitialData(
void ObjLoader::addOutputMaterialsAndFrames(
MeshBuilder2Data* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials, const u16& framesCount) {
@@ -113,44 +115,81 @@ void ObjLoader::setInitialData(
}
}
void ObjLoader::scan(MeshBuilder2Data* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials,
const u16& frameIndex) {
struct MaterialVertexCount {
size_t materialId;
int count;
};
std::vector<MaterialVertexCount> materialVertexCounts;
for (size_t i = 0; i < materials.size(); i++) {
MaterialVertexCount counter = {i, 0};
materialVertexCounts.push_back(counter);
}
for (size_t s = 0; s < shapes.size(); s++) {
const auto& mesh = shapes[s].mesh;
for (size_t f = 0; f < mesh.num_face_vertices.size(); f++) {
const auto& materialId = mesh.material_ids[f];
const auto& vertCountPerFace = size_t(mesh.num_face_vertices[f]);
TYRA_ASSERT(vertCountPerFace == 3,
"TinyObjLoader should triangulate mesh, internal error!");
materialVertexCounts[materialId].count += vertCountPerFace;
}
}
for (size_t i = 0; i < materials.size(); i++) {
const auto& counter = materialVertexCounts[i];
auto* outFrame = output->materials[i]->frames[frameIndex];
outFrame->count = counter.count;
outFrame->vertices = new Vec4[counter.count];
if (output->textureCoordsEnabled)
outFrame->textureCoords = new Vec4[counter.count];
if (output->normalsEnabled) outFrame->normals = new Vec4[counter.count];
}
}
void ObjLoader::importFrame(MeshBuilder2Data* output,
const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials,
const u16& frameIndex, const float& scale,
const bool& invertY, const u16& count) {
for (size_t i = 0; i < shapes.size(); i++) {
const auto& mesh = shapes[i].mesh;
struct MaterialInsertControl {
size_t materialId;
int inserted;
};
std::vector<MaterialInsertControl> materialInsertControls;
for (size_t i = 0; i < materials.size(); i++) {
MaterialInsertControl control = {i, 0};
materialInsertControls.push_back(control);
}
// Loop over shapes
for (size_t s = 0; s < shapes.size(); s++) {
const auto& mesh = shapes[s].mesh;
size_t index_offset = 0;
// Loop over faces
for (size_t f = 0; f < mesh.num_face_vertices.size(); f++) {
auto materialId = mesh.material_ids[f];
auto& materialInsertControl = materialInsertControls[materialId];
size_t vertCountPerFace = size_t(mesh.num_face_vertices[f]);
auto* outFrame = output->materials[materialId]->frames[frameIndex];
auto isAllocated = outFrame->vertices != nullptr;
if (!isAllocated) {
auto vertCount = mesh.num_face_vertices.size() * 3;
outFrame->count = vertCount;
outFrame->vertices = new Vec4[vertCount];
if (output->textureCoordsEnabled)
outFrame->textureCoords = new Vec4[vertCount];
if (output->normalsEnabled) outFrame->normals = new Vec4[vertCount];
} else {
TYRA_ASSERT(outFrame->count == mesh.num_face_vertices.size() * 3,
"Multiple usage of the same \"usemtl\" is not supported! "
"Please merge them!");
}
size_t fv = size_t(mesh.num_face_vertices[f]);
TYRA_ASSERT(count == 1 || fv == 3,
TYRA_ASSERT(count == 1 || vertCountPerFace == 3,
"Please triangulate obj files if you are animating!",
"Recommended Blender options: ",
"- Obj exporting: triangulate off, keep vertex order",
@@ -158,30 +197,26 @@ void ObjLoader::importFrame(MeshBuilder2Data* output,
"modifiers");
// Loop over vertices in the face.
for (size_t v = 0; v < fv; v++) {
for (size_t v = 0; v < vertCountPerFace; v++) {
// access to vertex
tinyobj::index_t idx = mesh.indices[index_offset + v];
tinyobj::real_t vx =
attrib.vertices[3 * size_t(idx.vertex_index) + 0];
tinyobj::real_t vy =
attrib.vertices[3 * size_t(idx.vertex_index) + 1];
tinyobj::real_t vz =
attrib.vertices[3 * size_t(idx.vertex_index) + 2];
tinyobj::real_t vx = attrib.vertices[3 * size_t(idx.vertex_index) + 0];
tinyobj::real_t vy = attrib.vertices[3 * size_t(idx.vertex_index) + 1];
tinyobj::real_t vz = attrib.vertices[3 * size_t(idx.vertex_index) + 2];
outFrame->vertices[index_offset + v].set(vx, vy, vz, 1.0F);
outFrame->vertices[index_offset + v] *= scale;
outFrame->vertices[materialInsertControl.inserted].set(vx, vy, vz,
1.0F);
outFrame->vertices[materialInsertControl.inserted] *= scale;
// Check if `normal_index` is zero or positive. negative = no normal
// data
if (idx.normal_index >= 0) {
tinyobj::real_t nx =
attrib.normals[3 * size_t(idx.normal_index) + 0];
tinyobj::real_t ny =
attrib.normals[3 * size_t(idx.normal_index) + 1];
tinyobj::real_t nz =
attrib.normals[3 * size_t(idx.normal_index) + 2];
tinyobj::real_t nx = attrib.normals[3 * size_t(idx.normal_index) + 0];
tinyobj::real_t ny = attrib.normals[3 * size_t(idx.normal_index) + 1];
tinyobj::real_t nz = attrib.normals[3 * size_t(idx.normal_index) + 2];
outFrame->normals[index_offset + v].set(nx, ny, nz, 1.0F);
outFrame->normals[materialInsertControl.inserted].set(nx, ny, nz,
1.0F);
}
// Check if `texcoord_index` is zero or positive. negative =
@@ -193,13 +228,14 @@ void ObjLoader::importFrame(MeshBuilder2Data* output,
attrib.texcoords[2 * size_t(idx.texcoord_index) + 1];
auto finalY = invertY ? 1.0F - ty : ty;
outFrame->textureCoords[index_offset + v].set(tx, finalY, 1.0F,
0.0F);
}
outFrame->textureCoords[materialInsertControl.inserted].set(
tx, finalY, 1.0F, 0.0F);
}
index_offset += fv;
materialInsertControl.inserted++;
}
index_offset += vertCountPerFace;
}
}
}
+2 -1
View File
@@ -30,7 +30,8 @@ Plane::~Plane() {}
// Methods
// ----
/** Set plane by specyfying 3 points.
/**
* Set plane by specyfying 3 points.
* This function assumes that the points
* are given in counter clockwise order
*/
@@ -15,21 +15,6 @@
namespace Tyra {
DynamicMesh::DynamicMesh(const MeshBuilderData& data) : Mesh(data) {
framesCount = data.framesCount;
TYRA_WARN(
"Frames count should be greater than 1 for DynamicMesh! Maybe you "
"should use StaticMesh?");
frames = new MeshFrame*[framesCount];
for (u32 i = 0; i < framesCount; i++) {
frames[i] = new MeshFrame(data, i);
}
initAnimation();
}
DynamicMesh::DynamicMesh(const MeshBuilder2Data& data) : Mesh(data) {
framesCount = data.materials[0]->frames.size();
-16
View File
@@ -13,22 +13,6 @@
namespace Tyra {
Mesh::Mesh(const MeshBuilderData& data) {
init();
TYRA_ASSERT(data.materialsCount > 0,
"Materials count must be greater than 0");
materialsCount = data.materialsCount;
materials = new MeshMaterial*[materialsCount];
for (u32 i = 0; i < materialsCount; i++) {
materials[i] = new MeshMaterial(data, i);
}
_isMother = true;
}
Mesh::Mesh(const MeshBuilder2Data& data) {
init();
@@ -19,18 +19,6 @@
namespace Tyra {
MeshFrame::MeshFrame(const MeshBuilderData& data, const u32& index) {
TYRA_ASSERT(index < data.framesCount && index >= 0, "Provided index \"",
index, "\" is out of range");
id = rand() % 1000000;
bbox =
new BBox(data.frames[index]->vertices, data.frames[index]->verticesCount);
_isMother = true;
}
MeshFrame::MeshFrame(const MeshBuilder2Data& data, const u32& index) {
id = rand() % 1000000;
@@ -51,35 +51,6 @@ MeshMaterial::MeshMaterial(const MeshBuilder2Data& data,
_isMother = true;
}
MeshMaterial::MeshMaterial(const MeshBuilderData& data,
const u32& materialIndex)
: color(false) {
TYRA_ASSERT(materialIndex < data.materialsCount && materialIndex >= 0,
"Provided index \"", materialIndex, "\" is out of range");
id = rand() % 1000000;
if (data.manyColorsEnabled) {
singleColorFlag = false;
TYRA_ASSERT(data.frames[0]->colors != nullptr, "Colors faces are required");
} else {
singleColorFlag = true;
}
color.set(128.0F, 128.0F, 128.0F, 128.0F);
_name = data.materials[materialIndex]->name;
TYRA_ASSERT(_name.length() > 0, "MeshMaterial name cannot be empty");
framesCount = data.framesCount;
frames = new MeshMaterialFrame*[framesCount];
for (u32 i = 0; i < framesCount; i++) {
frames[i] = new MeshMaterialFrame(data, i, materialIndex);
}
_isMother = true;
}
MeshMaterial::MeshMaterial(const MeshMaterial& mesh) {
id = rand() % 1000000;
@@ -14,33 +14,10 @@
#include <iomanip>
#include <string>
#include "renderer/models/color.hpp"
#include "loaders/3d/builder/mesh_builder_data.hpp"
#include "renderer/3d/mesh/mesh_material_frame.hpp"
namespace Tyra {
MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data,
const u32& frameIndex,
const u32& materialIndex) {
TYRA_ASSERT(frameIndex < data.framesCount && frameIndex >= 0,
"Provided index \"", frameIndex, "\" is out of range");
TYRA_ASSERT(materialIndex < data.materialsCount && materialIndex >= 0,
"Provided index \"", materialIndex, "\" is out of range");
id = rand() % 1000000;
bbox = new BBox(data.frames[frameIndex]->vertices,
data.materials[materialIndex]->vertexFaces,
data.materials[materialIndex]->count);
allocateVertices(data, frameIndex, materialIndex);
allocateNormals(data, frameIndex, materialIndex);
allocateTextureCoords(data, frameIndex, materialIndex);
allocateColors(data, frameIndex, materialIndex);
_isMother = true;
}
MeshMaterialFrame::MeshMaterialFrame(const MeshBuilder2Data& data,
const u32& frameIndex,
const u32& materialIndex) {
@@ -67,21 +44,9 @@ MeshMaterialFrame::MeshMaterialFrame(const MeshBuilder2Data& data,
count = frame->count;
vertices = frame->vertices;
if (data.normalsEnabled)
normals = frame->normals;
else
normals = nullptr;
if (data.textureCoordsEnabled)
textureCoords = frame->textureCoords;
else
textureCoords = nullptr;
if (data.lightMapEnabled)
colors = frame->colors;
else
colors = nullptr;
_isMother = true;
}
@@ -111,74 +76,6 @@ MeshMaterialFrame::~MeshMaterialFrame() {
}
}
void MeshMaterialFrame::allocateVertices(const MeshBuilderData& data,
const u32& frameIndex,
const u32& materialIndex) {
count = data.materials[materialIndex]->count; // faces count
vertices = new Vec4[count];
TYRA_ASSERT(count > 0, "Vertex count must be greater than 0");
auto* rolled = data.frames[frameIndex]->vertices;
auto* faces = data.materials[materialIndex]->vertexFaces;
TYRA_ASSERT(rolled != nullptr, "Vertices are required");
TYRA_ASSERT(faces != nullptr, "Vertex faces are required");
for (u32 i = 0; i < count; i++) vertices[i] = rolled[faces[i]];
}
void MeshMaterialFrame::allocateTextureCoords(const MeshBuilderData& data,
const u32& frameIndex,
const u32& materialIndex) {
textureCoords = nullptr;
if (!data.textureCoordsEnabled) return;
textureCoords = new Vec4[count];
auto* rolled = data.frames[frameIndex]->textureCoords;
auto* faces = data.materials[materialIndex]->textureCoordFaces;
TYRA_ASSERT(rolled != nullptr, "Texture coordinates are required");
TYRA_ASSERT(faces != nullptr, "Texture coordinate faces are required");
for (u32 i = 0; i < count; i++) textureCoords[i] = rolled[faces[i]];
}
void MeshMaterialFrame::allocateNormals(const MeshBuilderData& data,
const u32& frameIndex,
const u32& materialIndex) {
normals = nullptr;
if (!data.normalsEnabled) return;
normals = new Vec4[count];
auto* rolled = data.frames[frameIndex]->normals;
auto* faces = data.materials[materialIndex]->normalFaces;
TYRA_ASSERT(rolled != nullptr, "Normals are required");
TYRA_ASSERT(faces != nullptr, "Normal faces are required");
for (u32 i = 0; i < count; i++) normals[i] = rolled[faces[i]];
}
void MeshMaterialFrame::allocateColors(const MeshBuilderData& data,
const u32& frameIndex,
const u32& materialIndex) {
colors = nullptr;
if (!data.manyColorsEnabled) return;
colors = new Color[count];
auto* rolled = data.frames[frameIndex]->colors;
auto* faces = data.materials[materialIndex]->colorFaces;
TYRA_ASSERT(rolled != nullptr, "Colors are required");
TYRA_ASSERT(faces != nullptr, "Color faces are required");
for (u32 i = 0; i < count; i++) colors[i] = rolled[faces[i]];
}
std::string MeshMaterialFrame::getPrint(const char* name) const {
std::stringstream res;
if (name) {
@@ -13,16 +13,6 @@
namespace Tyra {
StaticMesh::StaticMesh(const MeshBuilderData& data) : Mesh(data) {
TYRA_ASSERT(data.framesCount > 0, "Frames count must be greater than 0");
if (data.framesCount > 1)
TYRA_WARN("Static meshes should have only one frame, but ",
data.framesCount, " frames were found");
frame = new MeshFrame(data, 0);
}
StaticMesh::StaticMesh(const MeshBuilder2Data& data) : Mesh(data) {
if (data.materials[0]->frames.size() > 1)
TYRA_WARN("Static meshes should have only one frame, but ",
@@ -30,6 +30,8 @@ void DynPipRenderer::allocateOnUse(const u32& t_packetSize) {
staticDataPacket = packet2_create(3, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
objectDataPacket = packet2_create(16, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
packetSize = t_packetSize;
for (u16 i = 0; i < 2; i++)
packets[i] =
packet2_create(t_packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, true);
@@ -174,6 +176,10 @@ void DynPipRenderer::addBufferDataToPacket(DynPipVU1Program* program,
void DynPipRenderer::sendPacket() {
dma_channel_wait(DMA_CHANNEL_VIF1, 0);
dma_channel_send_packet2(currentPacket, DMA_CHANNEL_VIF1, true);
TYRA_ASSERT(packet2_get_qw_count(currentPacket) <= packetSize,
"Packet is too big. Internal error.");
// Switch packet, so we can proceed during DMA transfer
context = !context;
}
@@ -36,6 +36,7 @@ void StaPipClipper::clip(StaPipQBuffer* buffer) {
for (u32 i = 0; i < buffer->size / 3; i++) {
for (u8 j = 0; j < 3; j++) {
inputVerts[j] = *mvp * buffer->vertices[i * 3 + j];
inputTriangle[j] = {
&inputVerts[j],
buffer->bag->lighting ? &buffer->normals[i * 3 + j] : nullptr,
@@ -123,7 +123,7 @@ void StaPipCore::render(StaPipBag* bag, StaPipBagPackagesBBox* bbox) {
rendererCore->renderer3D.frustumPlanes.getAll(), *bag->info->model);
if (frustumCheck == OUTSIDE_FRUSTUM) {
if (frustumCull && !bbox) {
if (!bbox) {
delete renderBbox;
}
return;
@@ -206,6 +206,7 @@ void StaPipCore::render(StaPipBag* bag, StaPipBagPackagesBBox* bbox) {
if (frustumCull && !bbox) {
delete renderBbox;
}
if (texBuffers) delete texBuffers;
qbufferRenderer.flushBuffers();
@@ -162,7 +162,8 @@ void StaPipQBuffer::reallocateManually(const u16& t_size) {
}
void StaPipQBuffer::deallocateDynamicData() {
if (_isDynamicallyAllocated) {
if (!_isDynamicallyAllocated) return;
delete[] vertices;
if (_stAllocated) {
@@ -181,30 +182,33 @@ void StaPipQBuffer::deallocateDynamicData() {
}
_isDynamicallyAllocated = false;
}
}
/** When we not receive maxVertCount vertices, we must align it by ourself.
* Too bad - not efficient. */
/**
* When we not receive maxVertCount vertices, we must align it by ourself.
* Too bad - not efficient.
*/
void StaPipQBuffer::allocateDynamicData(u16 size, StaPipBag* bag) {
TYRA_ASSERT(size <= maxVertCount, "Wrong size. Max buffer size in VU1 is ",
maxVertCount, ". Provided: ", size);
TYRA_ASSERT(!_isDynamicallyAllocated, "Buffer is already allocated");
vertices = new (std::align_val_t(sizeof(VECTOR))) Vec4[size];
if (size == 0) return;
vertices = new Vec4[size];
if (bag->texture != nullptr) {
sts = new (std::align_val_t(sizeof(VECTOR))) Vec4[size];
sts = new Vec4[size];
_stAllocated = true;
}
if (bag->color->many != nullptr) {
colors = new (std::align_val_t(sizeof(VECTOR))) Vec4[size];
colors = new Vec4[size];
_colorAllocated = true;
}
if (bag->lighting != nullptr) {
normals = new (std::align_val_t(sizeof(VECTOR))) Vec4[size];
normals = new Vec4[size];
_normalAllocated = true;
}
@@ -189,6 +189,7 @@ CoreBBoxFrustum CoreBBox::isInFrustum(const Plane* frustumPlanes,
const auto margin = margins == nullptr ? 0.0F : margins[i];
boxOut = 0;
boxIn = 0;
// for each corner of the box do ...
// get out of the cycle as soon as a box as corners
// both inside and out of the frustum
@@ -202,6 +203,7 @@ CoreBBoxFrustum CoreBBox::isInFrustum(const Plane* frustumPlanes,
else
boxIn++;
}
// if all corners are out
if (!boxIn)
return OUTSIDE_FRUSTUM;
@@ -46,16 +46,16 @@ CoreBBoxFrustum RenderBBox::clipIsInFrustum(const Plane* frustumPlanes,
// Oh no, it probably needs clipping
float margins[6]; // This probably needs more calibration
float guardBand[6]; // This probably needs more calibration
margins[0] = -15.0F; // Top
margins[1] = -10.0F; // BOTTOM
margins[2] = -25.0F; // LEFT
margins[3] = -25.0F; // RIGHT
margins[4] = -10.0F; // NEAR
margins[5] = -10.0F; // FAR
guardBand[0] = -15.0F; // Top
guardBand[1] = -10.0F; // BOTTOM
guardBand[2] = -25.0F; // LEFT
guardBand[3] = -25.0F; // RIGHT
guardBand[4] = -10.0F; // NEAR
guardBand[5] = -10.0F; // FAR
return isInFrustum(frustumPlanes, model, margins); // Let's check it again
}
return isInFrustum(frustumPlanes, model, guardBand); // Let's check it again
} // namespace Tyra
} // namespace Tyra
+1
View File
@@ -107,6 +107,7 @@ void Tutorial01 ::init() {
scales = new M4x4[blocksCount];
float center = (rows / 2.0F) * offset;
auto* color = new Color(128.0F, 128.0F, 128.0F, 128.0F);
for (u32 i = 0; i < blocksCount; i++) {
u32 column = i % columns;
u32 row = i / rows;