mesh patch 1
This commit is contained in:
+6
-3
@@ -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,11 +22,11 @@ class MD2Loader : public Loader {
|
||||
MD2Loader();
|
||||
~MD2Loader();
|
||||
|
||||
MeshBuilderData* load(const char* fullpath, const float& scale,
|
||||
const bool& invertT);
|
||||
MeshBuilder2Data* load(const char* fullpath, const float& scale,
|
||||
const bool& invertT);
|
||||
|
||||
inline MeshBuilderData* load(const std::string& fullpath, const float& scale,
|
||||
const bool& invertT) {
|
||||
inline MeshBuilder2Data* load(const std::string& fullpath, const float& scale,
|
||||
const bool& invertT) {
|
||||
return load(fullpath.c_str(), scale, invertT);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -34,10 +34,16 @@ class ObjLoader : public Loader {
|
||||
}
|
||||
|
||||
private:
|
||||
void setInitialData(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 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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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,8 +74,8 @@ MD2Loader::MD2Loader() {}
|
||||
|
||||
MD2Loader::~MD2Loader() {}
|
||||
|
||||
MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale,
|
||||
const bool& invertT) {
|
||||
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]) *
|
||||
scale,
|
||||
((frame->verts[i].v[1] * frame->scale[1]) + frame->translate[1]) *
|
||||
scale,
|
||||
((frame->verts[i].v[2] * frame->scale[2]) + frame->translate[2]) *
|
||||
scale);
|
||||
for (u32 vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) {
|
||||
temp.set(((frame->verts[vertexIndex].v[0] * frame->scale[0]) +
|
||||
frame->translate[0]) *
|
||||
scale,
|
||||
((frame->verts[vertexIndex].v[1] * frame->scale[1]) +
|
||||
frame->translate[1]) *
|
||||
scale,
|
||||
((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];
|
||||
for (u32 x = 0; x < framesCount; x++) {
|
||||
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;
|
||||
|
||||
@@ -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,93 +115,127 @@ 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;
|
||||
};
|
||||
|
||||
// Loop over shapes
|
||||
for (size_t s = 0; s < shapes.size(); s++) {
|
||||
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* outFrame = output->materials[materialId]->frames[frameIndex];
|
||||
std::vector<MaterialInsertControl> materialInsertControls;
|
||||
for (size_t i = 0; i < materials.size(); i++) {
|
||||
MaterialInsertControl control = {i, 0};
|
||||
materialInsertControls.push_back(control);
|
||||
}
|
||||
|
||||
auto isAllocated = outFrame->vertices != nullptr;
|
||||
// Loop over shapes
|
||||
for (size_t s = 0; s < shapes.size(); s++) {
|
||||
const auto& mesh = shapes[s].mesh;
|
||||
|
||||
if (!isAllocated) {
|
||||
auto vertCount = mesh.num_face_vertices.size() * 3;
|
||||
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]);
|
||||
|
||||
outFrame->count = vertCount;
|
||||
outFrame->vertices = new Vec4[vertCount];
|
||||
auto* outFrame = output->materials[materialId]->frames[frameIndex];
|
||||
|
||||
if (output->textureCoordsEnabled)
|
||||
outFrame->textureCoords = new Vec4[vertCount];
|
||||
TYRA_ASSERT(count == 1 || vertCountPerFace == 3,
|
||||
"Please triangulate obj files if you are animating!",
|
||||
"Recommended Blender options: ",
|
||||
"- Obj exporting: triangulate off, keep vertex order",
|
||||
"- Object modifiers: triangulate (as first!), then other "
|
||||
"modifiers");
|
||||
|
||||
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!");
|
||||
// Loop over vertices in the face.
|
||||
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];
|
||||
|
||||
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];
|
||||
|
||||
outFrame->normals[materialInsertControl.inserted].set(nx, ny, nz,
|
||||
1.0F);
|
||||
}
|
||||
|
||||
size_t fv = size_t(mesh.num_face_vertices[f]);
|
||||
// Check if `texcoord_index` is zero or positive. negative =
|
||||
// notexcoord data
|
||||
if (idx.texcoord_index >= 0) {
|
||||
tinyobj::real_t tx =
|
||||
attrib.texcoords[2 * size_t(idx.texcoord_index) + 0];
|
||||
tinyobj::real_t ty =
|
||||
attrib.texcoords[2 * size_t(idx.texcoord_index) + 1];
|
||||
|
||||
TYRA_ASSERT(count == 1 || fv == 3,
|
||||
"Please triangulate obj files if you are animating!",
|
||||
"Recommended Blender options: ",
|
||||
"- Obj exporting: triangulate off, keep vertex order",
|
||||
"- Object modifiers: triangulate (as first!), then other "
|
||||
"modifiers");
|
||||
|
||||
// Loop over vertices in the face.
|
||||
for (size_t v = 0; v < fv; 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];
|
||||
|
||||
outFrame->vertices[index_offset + v].set(vx, vy, vz, 1.0F);
|
||||
outFrame->vertices[index_offset + v] *= 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];
|
||||
|
||||
outFrame->normals[index_offset + v].set(nx, ny, nz, 1.0F);
|
||||
}
|
||||
|
||||
// Check if `texcoord_index` is zero or positive. negative =
|
||||
// notexcoord data
|
||||
if (idx.texcoord_index >= 0) {
|
||||
tinyobj::real_t tx =
|
||||
attrib.texcoords[2 * size_t(idx.texcoord_index) + 0];
|
||||
tinyobj::real_t ty =
|
||||
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);
|
||||
}
|
||||
auto finalY = invertY ? 1.0F - ty : ty;
|
||||
outFrame->textureCoords[materialInsertControl.inserted].set(
|
||||
tx, finalY, 1.0F, 0.0F);
|
||||
}
|
||||
|
||||
index_offset += fv;
|
||||
materialInsertControl.inserted++;
|
||||
}
|
||||
|
||||
index_offset += vertCountPerFace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
normals = frame->normals;
|
||||
textureCoords = frame->textureCoords;
|
||||
colors = frame->colors;
|
||||
|
||||
_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,49 +162,53 @@ void StaPipQBuffer::reallocateManually(const u16& t_size) {
|
||||
}
|
||||
|
||||
void StaPipQBuffer::deallocateDynamicData() {
|
||||
if (_isDynamicallyAllocated) {
|
||||
delete[] vertices;
|
||||
if (!_isDynamicallyAllocated) return;
|
||||
|
||||
if (_stAllocated) {
|
||||
delete[] sts;
|
||||
_stAllocated = false;
|
||||
}
|
||||
delete[] vertices;
|
||||
|
||||
if (_colorAllocated) {
|
||||
delete[] colors;
|
||||
_colorAllocated = false;
|
||||
}
|
||||
|
||||
if (_normalAllocated) {
|
||||
delete[] normals;
|
||||
_normalAllocated = false;
|
||||
}
|
||||
|
||||
_isDynamicallyAllocated = false;
|
||||
if (_stAllocated) {
|
||||
delete[] sts;
|
||||
_stAllocated = false;
|
||||
}
|
||||
|
||||
if (_colorAllocated) {
|
||||
delete[] colors;
|
||||
_colorAllocated = false;
|
||||
}
|
||||
|
||||
if (_normalAllocated) {
|
||||
delete[] normals;
|
||||
_normalAllocated = false;
|
||||
}
|
||||
|
||||
_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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user