mesh refactor 3

This commit is contained in:
h4570
2022-08-10 21:58:32 +02:00
parent 10e0f52d44
commit 0a2d19b2d0
26 changed files with 321 additions and 356 deletions
+4 -11
View File
@@ -1,18 +1,9 @@
------------ Tyra's v2.0 roadmap to publish on GitHub ------------ ------------ Tyra's v2.0 roadmap to publish on GitHub ------------
- [Obj] soldier_000001
- [General] vec3/vec4/m4x4 functions from ms
- [General] wszystkie new M4x4 i = M4x4 na M4x4::Identity
- [General] std::vector in mesh instead of array**
- [General] Allow to edit all data from mesh/texture
- [General] manycolor -> lightmap
- [General] rename invertT -> invertY
- [General] ładować ambient i wrzucać do material. Zmienic nazwe na ambient
- [General] odpalic de_dust2, doszlifowac guard band
- [General] odpalic de_dust2, doszlifowac guard band
- [Demo] Create cool demo which will show all features of Tyra
- [General] USB test - [General] USB test
- [General] Tyra version, render it on start - [General] Tyra version, render it on start
- [Renderer] Fog
- [Demo] Create cool demo which will show all features of Tyra
- [General] CI in Github via docker image - [General] CI in Github via docker image
@@ -40,6 +31,8 @@ because Mesh rendering uses only core.render()
- [General] Credits: clipping, obj loader - [General] Credits: clipping, obj loader
------------ Github issues for Tyra v2 ------------ ------------ Github issues for Tyra v2 ------------
- [rendere] fog
- [rendere] bbox parts optimization
- [md2] refactor - [md2] refactor
- [3D] Add drawLine(x, y , color, size) - [3D] Add drawLine(x, y , color, size)
- [2D] Fixed font support - [2D] Fixed font support
+8 -2
View File
@@ -15,18 +15,24 @@
using Tyra::Color; using Tyra::Color;
using Tyra::FileUtils; using Tyra::FileUtils;
using Tyra::ObjLoader; using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo { namespace Demo {
DebugObject::DebugObject(TextureRepository* repo) { DebugObject::DebugObject(TextureRepository* repo) {
ObjLoader loader; ObjLoader loader;
ObjLoaderOptions objOptions;
objOptions.flipUVs = true;
objOptions.scale = .5F;
auto* data = auto* data =
loader.load(FileUtils::fromCwd("game/models/debug.obj"), 1, .5F, true); loader.load(FileUtils::fromCwd("game/models/debug.obj"), objOptions);
data->normalsEnabled = false; data->normalsEnabled = false;
data->textureCoordsEnabled = false; data->textureCoordsEnabled = false;
mesh = new StaticMesh(*data); mesh = new StaticMesh(*data);
delete data; delete data;
mesh->getMaterial(0)->color = Color(192.0F, 32.0F, 32.0F, 128.0F);
rotator = 0.0F; rotator = 0.0F;
allocateOptions(); allocateOptions();
+8 -2
View File
@@ -14,20 +14,26 @@
using Tyra::FileUtils; using Tyra::FileUtils;
using Tyra::ObjLoader; using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo { namespace Demo {
Enemy::Enemy(TextureRepository* repo) { Enemy::Enemy(TextureRepository* repo) {
ObjLoader loader; ObjLoader loader;
ObjLoaderOptions objOptions;
objOptions.animation.count = 4;
objOptions.flipUVs = true;
objOptions.scale = 25.0F;
auto* bodyData = loader.load( auto* bodyData = loader.load(
FileUtils::fromCwd("game/models/soldier/soldier.obj"), 4, 25.0F, true); FileUtils::fromCwd("game/models/soldier/soldier.obj"), objOptions);
bodyData->normalsEnabled = false; bodyData->normalsEnabled = false;
bodyMesh = new DynamicMesh(*bodyData); bodyMesh = new DynamicMesh(*bodyData);
delete bodyData; delete bodyData;
bodyMesh->playAnimation(0, bodyMesh->getFramesCount() - 1); bodyMesh->playAnimation(0, bodyMesh->frames.size() - 1);
bodyMesh->setAnimSpeed(0.1F); bodyMesh->setAnimSpeed(0.1F);
repo->addByMesh(bodyMesh, FileUtils::fromCwd("game/models/soldier/"), "png"); repo->addByMesh(bodyMesh, FileUtils::fromCwd("game/models/soldier/"), "png");
+8 -6
View File
@@ -14,21 +14,23 @@
using Tyra::FileUtils; using Tyra::FileUtils;
using Tyra::ObjLoader; using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo { namespace Demo {
Weapon::Weapon(TextureRepository* repo) { Weapon::Weapon(TextureRepository* repo) {
ObjLoader loader; ObjLoader loader;
auto* data = loader.load(FileUtils::fromCwd("game/models/ak47/ak47.obj"), 1,
.5F, true); ObjLoaderOptions objOptions;
objOptions.flipUVs = true;
objOptions.scale = .5F;
auto* data =
loader.load(FileUtils::fromCwd("game/models/ak47/ak47.obj"), objOptions);
data->normalsEnabled = false; data->normalsEnabled = false;
mesh = new StaticMesh(*data); mesh = new StaticMesh(*data);
delete data; delete data;
mesh->getMaterial(0)->color.r = 64.0F;
mesh->getMaterial(0)->color.g = 64.0F;
mesh->getMaterial(0)->color.b = 64.0F;
mesh->translation.translateX(2.85F); mesh->translation.translateX(2.85F);
mesh->translation.translateY(-3.40F); mesh->translation.translateY(-3.40F);
mesh->translation.translateZ(-10.50F); mesh->translation.translateZ(-10.50F);
+7 -8
View File
@@ -14,24 +14,23 @@
using Tyra::FileUtils; using Tyra::FileUtils;
using Tyra::ObjLoader; using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo { namespace Demo {
Skybox::Skybox(TextureRepository* repo) { Skybox::Skybox(TextureRepository* repo) {
ObjLoader loader; ObjLoader loader;
ObjLoaderOptions objOptions;
objOptions.flipUVs = true;
objOptions.scale = 100.0F;
auto* data = loader.load(FileUtils::fromCwd("game/models/skybox/skybox.obj"), auto* data = loader.load(FileUtils::fromCwd("game/models/skybox/skybox.obj"),
1, 100.0F, true); objOptions);
data->normalsEnabled = false; data->normalsEnabled = false;
mesh = new StaticMesh(*data); mesh = new StaticMesh(*data);
delete data; delete data;
for (u32 i = 0; i < mesh->getMaterialsCount(); i++) {
auto* material = mesh->getMaterial(i);
material->color.r = 16.0F;
material->color.g = 16.0F;
material->color.b = 16.0F;
}
repo->addByMesh(mesh, FileUtils::fromCwd("game/models/skybox/"), "png"); repo->addByMesh(mesh, FileUtils::fromCwd("game/models/skybox/"), "png");
allocateOptions(); allocateOptions();
+8 -4
View File
@@ -14,6 +14,7 @@
using Tyra::FileUtils; using Tyra::FileUtils;
using Tyra::ObjLoader; using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo { namespace Demo {
Terrain::Terrain(TextureRepository* repo) Terrain::Terrain(TextureRepository* repo)
@@ -23,13 +24,16 @@ Terrain::Terrain(TextureRepository* repo)
Vec4(286.0F, 0.0F, 443.3F, 1.0F) // Right down Vec4(286.0F, 0.0F, 443.3F, 1.0F) // Right down
) { ) {
ObjLoader loader; ObjLoader loader;
ObjLoaderOptions objOptions;
objOptions.flipUVs = true;
objOptions.scale = 25.0F;
auto* data = loader.load( auto* data = loader.load(
FileUtils::fromCwd("game/models/terrain/terrain.obj"), 1, 25.0F, true); FileUtils::fromCwd("game/models/terrain/terrain.obj"), objOptions);
data->normalsEnabled = false; data->normalsEnabled = false;
mesh = new StaticMesh(*data); mesh = new StaticMesh(*data);
mesh->getMaterial(0)->color.r = 32.0F;
mesh->getMaterial(0)->color.g = 32.0F;
mesh->getMaterial(0)->color.b = 32.0F;
delete data; delete data;
repo->addByMesh(mesh, FileUtils::fromCwd("game/models/terrain/"), "png"); repo->addByMesh(mesh, FileUtils::fromCwd("game/models/terrain/"), "png");
@@ -16,19 +16,21 @@
namespace Tyra { namespace Tyra {
struct MD2LoaderOptions {
bool flipUVs = false;
float scale = 1.0F;
};
/** Class responsible for loading & parsing Quake's II ".md2" 3D files */ /** Class responsible for loading & parsing Quake's II ".md2" 3D files */
class MD2Loader : public Loader { class MD2Loader : public Loader {
public: public:
MD2Loader(); MD2Loader();
~MD2Loader(); ~MD2Loader();
MeshBuilderData* load(const char* fullpath, const float& scale, MeshBuilderData* load(const char* fullpath);
const bool& invertT); MeshBuilderData* load(const char* fullpath, MD2LoaderOptions options);
MeshBuilderData* load(const std::string& fullpath);
inline MeshBuilderData* load(const std::string& fullpath, const float& scale, MeshBuilderData* load(const std::string& fullpath, MD2LoaderOptions options);
const bool& invertT) {
return load(fullpath.c_str(), scale, invertT);
}
}; };
} // namespace Tyra } // namespace Tyra
@@ -23,35 +23,17 @@ class DynamicMesh : public Mesh {
explicit DynamicMesh(const DynamicMesh& mesh); explicit DynamicMesh(const DynamicMesh& mesh);
~DynamicMesh(); ~DynamicMesh();
const DynamicMeshAnimState& getAnimState() const { return animState; } std::vector<MeshFrame*> frames;
/** Returns single frame. */ DynamicMeshAnimState animState;
MeshFrame* getFrame(const u32& i) { return frames[i]; }
MeshFrame** getFrames() { return frames; }
/** Count of frames. Static object (not animated) will have only 1 frame. */
const u32& getFramesCount() const { return framesCount; }
const u32& getCurrentAnimationFrame() const { return animState.currentFrame; }
const u32& getNextAnimationFrame() const { return animState.nextFrame; }
const u32& getStartAnimationFrame() const { return animState.startFrame; }
const u32& getEndAnimationFrame() const { return animState.endFrame; }
const u32& getStayAnimationFrame() const { return animState.stayFrame; }
void setCurrentAnimationFrame(const u32& v) { animState.currentFrame = v; }
void setNextAnimationFrame(const u32& v) { animState.nextFrame = v; }
void setStartAnimationFrame(const u32& v) { animState.startFrame = v; }
void setEndAnimationFrame(const u32& v) { animState.endFrame = v; }
void setStayAnimationFrame(const u32& v) { animState.stayFrame = v; }
/** @returns bounding box object of current frame. */ /** @returns bounding box object of current frame. */
const BBox& getCurrentBoundingBox() const { const BBox& getCurrentBoundingBox() const {
return frames[animState.currentFrame]->getBBox(); return *frames[animState.currentFrame]->bbox;
} }
/** Loop in one frame */ /** Loop in one frame */
void playAnimation(const u32& t_frame) { playAnimation(t_frame, t_frame); } void playAnimation(const u32& t_frame);
/** Play animation in loop from startFrame to endFrame */ /** Play animation in loop from startFrame to endFrame */
void playAnimation(const u32& t_startFrame, const u32& t_endFrame); void playAnimation(const u32& t_startFrame, const u32& t_endFrame);
@@ -73,9 +55,6 @@ class DynamicMesh : public Mesh {
private: private:
void initAnimation(); void initAnimation();
DynamicMeshAnimState animState;
u32 framesCount;
MeshFrame** frames;
}; };
} // namespace Tyra } // namespace Tyra
+5 -18
View File
@@ -23,17 +23,14 @@ class Mesh {
explicit Mesh(const Mesh& mesh); explicit Mesh(const Mesh& mesh);
~Mesh(); ~Mesh();
/** Translation matrix */ u8 isMother;
M4x4 translation;
/** Rotation matrix */ u32 id;
M4x4 rotation;
/** Scale matrix */ M4x4 translation, rotation, scale;
M4x4 scale;
std::vector<MeshMaterial*> materials;
inline const u32& getId() const { return id; }
inline const u8& isMother() const { return _isMother; }
M4x4 getModelMatrix() const; M4x4 getModelMatrix() const;
/** Get position from translation matrix */ /** Get position from translation matrix */
@@ -43,18 +40,8 @@ class Mesh {
void setPosition(const Vec4& v); void setPosition(const Vec4& v);
/** Returns material, which is a mesh "subgroup". */
MeshMaterial* getMaterial(const u32& i) const { return materials[i]; }
MeshMaterial** getMaterials() { return materials; }
const u32& getMaterialsCount() const { return materialsCount; }
protected: protected:
void init(); void init();
u8 _isMother;
u32 id, materialsCount;
MeshMaterial** materials;
}; };
} // namespace Tyra } // namespace Tyra
+5 -8
View File
@@ -22,19 +22,16 @@ class MeshFrame {
explicit MeshFrame(const MeshFrame& frame); explicit MeshFrame(const MeshFrame& frame);
~MeshFrame(); ~MeshFrame();
const u32& getId() const { return id; } u8 isMother;
const u8& isMother() const { return _isMother; }
const BBox& getBBox() const { return *bbox; } u32 id;
BBox* bbox;
void print() const; void print() const;
void print(const char* name) const; void print(const char* name) const;
void print(const std::string& name) const { print(name.c_str()); } void print(const std::string& name) const { print(name.c_str()); }
std::string getPrint(const char* name = nullptr) const; std::string getPrint(const char* name = nullptr) const;
private:
u8 _isMother;
BBox* bbox;
u32 id;
}; };
} // namespace Tyra } // namespace Tyra
+7 -18
View File
@@ -22,33 +22,22 @@ class MeshMaterial {
explicit MeshMaterial(const MeshMaterial& material); explicit MeshMaterial(const MeshMaterial& material);
~MeshMaterial(); ~MeshMaterial();
Color color; u8 isMother, lightmapFlag;
const u32& getId() const { return id; } u32 id;
const std::string& getName() const { return _name; }
const u8& isMother() const { return _isMother; }
const u32& getFramesCount() const { return framesCount; }
const u8& isSingleColorActivated() const {
return singleColorFlag;
} // TODO: colormode -> color / lightmap
MeshMaterialFrame** getFrames() const { return frames; } std::string name;
MeshMaterialFrame* getFrame(const u32& i) const { return frames[i]; }
Color ambient;
std::vector<MeshMaterialFrame*> frames;
const BBox& getBBox(const u32& frame) const; const BBox& getBBox(const u32& frame) const;
void setSingleColorFlag(const u8& flag);
void print() const; void print() const;
void print(const char* name) const; void print(const char* name) const;
void print(const std::string& name) const { print(name.c_str()); } void print(const std::string& name) const { print(name.c_str()); }
std::string getPrint(const char* name = nullptr) const; std::string getPrint(const char* name = nullptr) const;
private:
MeshMaterialFrame** frames;
std::string _name;
u8 _isMother, singleColorFlag;
u32 id, framesCount;
}; };
} // namespace Tyra } // namespace Tyra
@@ -22,28 +22,20 @@ class MeshMaterialFrame {
explicit MeshMaterialFrame(const MeshMaterialFrame& frame); explicit MeshMaterialFrame(const MeshMaterialFrame& frame);
~MeshMaterialFrame(); ~MeshMaterialFrame();
const u32& getId() const { return id; } u8 isMother;
const u8& isMother() const { return _isMother; }
const BBox& getBBox() const { return *bbox; }
const u32& getVertexCount() const { return count; } u32 id, count;
Vec4* getVertices() const { return vertices; }
Vec4* getNormals() const { return normals; } Vec4 *vertices, *textureCoords, *normals;
Vec4* getTextureCoords() const { return textureCoords; }
Color* getColors() const { return colors; } Color* colors;
BBox* bbox;
void print() const; void print() const;
void print(const char* name) const; void print(const char* name) const;
void print(const std::string& name) const { print(name.c_str()); } void print(const std::string& name) const { print(name.c_str()); }
std::string getPrint(const char* name = nullptr) const; std::string getPrint(const char* name = nullptr) const;
private:
BBox* bbox;
u8 _isMother;
u32 id, count;
Vec4 *vertices, *textureCoords, *normals;
Color* colors;
}; };
} // namespace Tyra } // namespace Tyra
@@ -22,12 +22,6 @@ class StaticMesh : public Mesh {
StaticMesh(const StaticMesh& mesh); StaticMesh(const StaticMesh& mesh);
~StaticMesh(); ~StaticMesh();
MeshFrame* getFrame() { return frame; }
/** @returns bounding box object of current frame. */
const BBox& getBoundingBox() const { return frame->getBBox(); }
private:
MeshFrame* frame; MeshFrame* frame;
}; };
@@ -30,10 +30,11 @@ class CoreBBox {
explicit CoreBBox(const std::vector<CoreBBox>& t_bboxes, explicit CoreBBox(const std::vector<CoreBBox>& t_bboxes,
const u32& startIndex, const u32& stopIndex); const u32& startIndex, const u32& stopIndex);
const Vec4& operator[](const u8& i) { return _vertices[i]; } Vec4 vertices[8];
const Vec4& operator[](const u8& i) { return vertices[i]; }
const u8 getVertexCount() { return 8; } const u8 getVertexCount() { return 8; }
const Vec4& getVertex(const u8& i) { return _vertices[i]; }
Vec4* getVertices() { return _vertices; }
void print() const; void print() const;
void print(const char* name) const; void print(const char* name) const;
@@ -42,9 +43,6 @@ class CoreBBox {
CoreBBoxFrustum isInFrustum(const Plane* frustumPlanes, const M4x4& model, CoreBBoxFrustum isInFrustum(const Plane* frustumPlanes, const M4x4& model,
const float* margins = nullptr) const; const float* margins = nullptr) const;
protected:
Vec4 _vertices[8];
}; };
} // namespace Tyra } // namespace Tyra
@@ -74,8 +74,21 @@ MD2Loader::MD2Loader() {}
MD2Loader::~MD2Loader() {} MD2Loader::~MD2Loader() {}
MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale, MeshBuilderData* MD2Loader::load(const char* fullpath) {
const bool& invertT) { return load(fullpath, MD2LoaderOptions());
}
MeshBuilderData* MD2Loader::load(const std::string& fullpath) {
return load(fullpath.c_str(), MD2LoaderOptions());
}
MeshBuilderData* MD2Loader::load(const std::string& fullpath,
MD2LoaderOptions options) {
return load(fullpath.c_str(), options);
}
MeshBuilderData* MD2Loader::load(const char* fullpath,
MD2LoaderOptions options) {
std::string path = fullpath; std::string path = fullpath;
TYRA_ASSERT(!path.empty(), "Provided path is empty!"); TYRA_ASSERT(!path.empty(), "Provided path is empty!");
@@ -142,13 +155,13 @@ MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale,
for (u32 vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) { for (u32 vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) {
temp.set(((frame->verts[vertexIndex].v[0] * frame->scale[0]) + temp.set(((frame->verts[vertexIndex].v[0] * frame->scale[0]) +
frame->translate[0]) * frame->translate[0]) *
scale, options.scale,
((frame->verts[vertexIndex].v[1] * frame->scale[1]) + ((frame->verts[vertexIndex].v[1] * frame->scale[1]) +
frame->translate[1]) * frame->translate[1]) *
scale, options.scale,
((frame->verts[vertexIndex].v[2] * frame->scale[2]) + ((frame->verts[vertexIndex].v[2] * frame->scale[2]) +
frame->translate[2]) * frame->translate[2]) *
scale); options.scale);
tempVertices[frameIndex][vertexIndex].set(temp); tempVertices[frameIndex][vertexIndex].set(temp);
@@ -167,7 +180,7 @@ MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale,
temp.set(static_cast<float>(texCoord->s) / header.skinwidth, temp.set(static_cast<float>(texCoord->s) / header.skinwidth,
static_cast<float>(texCoord->t) / header.skinheight, 1.0F, 0.0F); static_cast<float>(texCoord->t) / header.skinheight, 1.0F, 0.0F);
if (invertT) temp.y = 1.0F - temp.y; if (options.flipUVs) temp.y = 1.0F - temp.y;
for (u32 j = 0; j < framesCount; j++) tempTexCoords[j][i].set(temp); for (u32 j = 0; j < framesCount; j++) tempTexCoords[j][i].set(temp);
} }
+14 -14
View File
@@ -29,7 +29,7 @@ BBox::BBox(const BBox& t_bbox) : CoreBBox(t_bbox) { setData(); }
BBox::BBox(const BBox& t_bbox, const M4x4& t_matrix) { BBox::BBox(const BBox& t_bbox, const M4x4& t_matrix) {
for (u32 i = 0; i < 8; i++) { for (u32 i = 0; i < 8; i++) {
_vertices[i] = t_matrix * t_bbox._vertices[i]; vertices[i] = t_matrix * t_bbox.vertices[i];
} }
setData(); setData();
@@ -44,31 +44,31 @@ BBox BBox::getTransformed(const M4x4& t_matrix) {
void BBox::setData() { void BBox::setData() {
// This might be shortened with Vec4 operator overloading, but current // This might be shortened with Vec4 operator overloading, but current
// implementation is more human readable. // implementation is more human readable.
_height = _vertices[0].y - _vertices[2].y; _height = vertices[0].y - vertices[2].y;
_width = _vertices[0].x - _vertices[4].x; _width = vertices[0].x - vertices[4].x;
_depth = _vertices[0].z - _vertices[1].z; _depth = vertices[0].z - vertices[1].z;
_centerVector = _vertices[0]; _centerVector = vertices[0];
_centerVector.x += (_width / 2); _centerVector.x += (_width / 2);
_centerVector.y += (_height / 2); _centerVector.y += (_height / 2);
_centerVector.z += (_depth / 2); _centerVector.z += (_depth / 2);
// Z-Axis faces // Z-Axis faces
_frontFace = BBoxFace(_vertices[1], _vertices[7], _vertices[1].z); _frontFace = BBoxFace(vertices[1], vertices[7], vertices[1].z);
_backFace = BBoxFace(_vertices[0], _vertices[6], _vertices[0].z); _backFace = BBoxFace(vertices[0], vertices[6], vertices[0].z);
// X-Axis faces // X-Axis faces
_leftFace = BBoxFace(_vertices[0], _vertices[3], _vertices[0].x); _leftFace = BBoxFace(vertices[0], vertices[3], vertices[0].x);
_rightFace = BBoxFace(_vertices[4], _vertices[7], _vertices[4].x); _rightFace = BBoxFace(vertices[4], vertices[7], vertices[4].x);
// Y-Axis faces // Y-Axis faces
_topFace = BBoxFace(_vertices[2], _vertices[7], _vertices[2].y); _topFace = BBoxFace(vertices[2], vertices[7], vertices[2].y);
_bottomFace = BBoxFace(_vertices[0], _vertices[5], _vertices[0].y); _bottomFace = BBoxFace(vertices[0], vertices[5], vertices[0].y);
} }
Vec4 BBox::min() { Vec4 BBox::min() {
Vec4 temp, _min; Vec4 temp, _min;
u8 isInitialized = 0; u8 isInitialized = 0;
const Vec4* vertices = getVertices(); const Vec4* vertices = vertices;
for (u8 i = 0; i < 8; i++) { for (u8 i = 0; i < 8; i++) {
temp.set(vertices[i].x, vertices[i].y, vertices[i].z, 1.0F); temp.set(vertices[i].x, vertices[i].y, vertices[i].z, 1.0F);
if (isInitialized == 0) { if (isInitialized == 0) {
@@ -88,7 +88,7 @@ Vec4 BBox::max() {
Vec4 temp, _max; Vec4 temp, _max;
u8 isInitialized = 0; u8 isInitialized = 0;
const Vec4* vertices = getVertices(); const Vec4* vertices = vertices;
for (u8 i = 0; i < 8; i++) { for (u8 i = 0; i < 8; i++) {
temp.set(vertices[i].x, vertices[i].y, vertices[i].z, 1.0F); temp.set(vertices[i].x, vertices[i].y, vertices[i].z, 1.0F);
if (isInitialized == 0) { if (isInitialized == 0) {
@@ -108,7 +108,7 @@ void BBox::getMinMax(Vec4* res_min, Vec4* res_max) {
Vec4 temp = Vec4(); Vec4 temp = Vec4();
u8 isInitialized = 0; u8 isInitialized = 0;
const Vec4* vertices = getVertices(); const Vec4* vertices = vertices;
for (u8 i = 0; i < 8; i++) { for (u8 i = 0; i < 8; i++) {
temp.set(vertices[i].x, vertices[i].y, vertices[i].z, 1.0F); temp.set(vertices[i].x, vertices[i].y, vertices[i].z, 1.0F);
if (isInitialized == 0) { if (isInitialized == 0) {
@@ -16,38 +16,31 @@
namespace Tyra { namespace Tyra {
DynamicMesh::DynamicMesh(const MeshBuilderData& data) : Mesh(data) { DynamicMesh::DynamicMesh(const MeshBuilderData& data) : Mesh(data) {
framesCount = data.materials[0]->frames.size(); if (data.materials[0]->frames.size() == 1) {
if (framesCount == 1) {
TYRA_WARN( TYRA_WARN(
"Frames count should be greater than 1 for DynamicMesh! Maybe you " "Frames count should be greater than 1 for DynamicMesh! Maybe you "
"should use StaticMesh?"); "should use StaticMesh?");
} }
frames = new MeshFrame*[framesCount]; for (u32 i = 0; i < data.materials[0]->frames.size(); i++) {
for (u32 i = 0; i < framesCount; i++) { frames.push_back(new MeshFrame(data, i));
frames[i] = new MeshFrame(data, i);
} }
initAnimation(); initAnimation();
} }
DynamicMesh::DynamicMesh(const DynamicMesh& mesh) : Mesh(mesh) { DynamicMesh::DynamicMesh(const DynamicMesh& mesh) : Mesh(mesh) {
framesCount = mesh.framesCount; for (u32 i = 0; i < mesh.frames.size(); i++) {
frames.push_back(new MeshFrame(*mesh.frames[i]));
frames = new MeshFrame*[framesCount];
for (u32 i = 0; i < framesCount; i++) {
frames[i] = new MeshFrame(*mesh.frames[i]);
} }
initAnimation(); initAnimation();
} }
DynamicMesh::~DynamicMesh() { DynamicMesh::~DynamicMesh() {
for (u32 i = 0; i < framesCount; i++) { for (u32 i = 0; i < frames.size(); i++) {
delete frames[i]; delete frames[i];
} }
delete[] frames;
} }
void DynamicMesh::initAnimation() { void DynamicMesh::initAnimation() {
@@ -62,14 +55,18 @@ void DynamicMesh::initAnimation() {
animState.speed = 0.1F; animState.speed = 0.1F;
} }
void DynamicMesh::playAnimation(const u32& t_frame) {
playAnimation(t_frame, t_frame);
}
void DynamicMesh::playAnimation(const u32& t_startFrame, void DynamicMesh::playAnimation(const u32& t_startFrame,
const u32& t_endFrame) { const u32& t_endFrame) {
TYRA_ASSERT(framesCount > 0, TYRA_ASSERT(frames.size() > 0,
"Cant play animation, because no mesh data was loaded!"); "Cant play animation, because no mesh data was loaded!");
TYRA_ASSERT(framesCount != 1, TYRA_ASSERT(frames.size() != 1,
"Cant play animation, because this mesh have only one frame."); "Cant play animation, because this mesh have only one frame.");
TYRA_ASSERT( TYRA_ASSERT(
t_endFrame < framesCount, t_endFrame < frames.size(),
"End frame value is too high. Valid range: (0, getFramesCount()-1)"); "End frame value is too high. Valid range: (0, getFramesCount()-1)");
animState.startFrame = t_startFrame; animState.startFrame = t_startFrame;
animState.endFrame = t_endFrame; animState.endFrame = t_endFrame;
@@ -81,12 +78,12 @@ void DynamicMesh::playAnimation(const u32& t_startFrame,
void DynamicMesh::playAnimation(const u32& t_startFrame, const u32& t_endFrame, void DynamicMesh::playAnimation(const u32& t_startFrame, const u32& t_endFrame,
const u32& t_stayFrame) { const u32& t_stayFrame) {
TYRA_ASSERT(framesCount > 0, TYRA_ASSERT(frames.size() > 0,
"Cant play animation, because no mesh data was loaded!"); "Cant play animation, because no mesh data was loaded!");
TYRA_ASSERT(framesCount != 1, TYRA_ASSERT(frames.size() != 1,
"Cant play animation, because this mesh have only one frame."); "Cant play animation, because this mesh have only one frame.");
TYRA_ASSERT( TYRA_ASSERT(
t_endFrame < framesCount, t_endFrame < frames.size(),
"End frame value is too high. Valid range: (0, getFramesCount()-1)"); "End frame value is too high. Valid range: (0, getFramesCount()-1)");
animState.startFrame = t_startFrame; animState.startFrame = t_startFrame;
animState.endFrame = t_endFrame; animState.endFrame = t_endFrame;
+7 -15
View File
@@ -19,41 +19,33 @@ Mesh::Mesh(const MeshBuilderData& data) {
TYRA_ASSERT(data.materials.size() > 0, TYRA_ASSERT(data.materials.size() > 0,
"Materials count must be greater than 0"); "Materials count must be greater than 0");
materialsCount = data.materials.size(); for (u32 i = 0; i < data.materials.size(); i++) {
materials = new MeshMaterial*[materialsCount]; materials.push_back(new MeshMaterial(data, i));
for (u32 i = 0; i < materialsCount; i++) {
materials[i] = new MeshMaterial(data, i);
} }
_isMother = true; isMother = true;
} }
Mesh::Mesh(const Mesh& mesh) { Mesh::Mesh(const Mesh& mesh) {
init(); init();
materialsCount = mesh.materialsCount; for (u32 i = 0; i < mesh.materials.size(); i++) {
materials = new MeshMaterial*[materialsCount]; materials.push_back(new MeshMaterial(*mesh.materials[i]));
for (u32 i = 0; i < materialsCount; i++) {
materials[i] = new MeshMaterial(*mesh.materials[i]);
} }
_isMother = false; isMother = false;
} }
M4x4 Mesh::getModelMatrix() const { return translation * rotation * scale; } M4x4 Mesh::getModelMatrix() const { return translation * rotation * scale; }
Mesh::~Mesh() { Mesh::~Mesh() {
for (u32 i = 0; i < materialsCount; i++) { for (u32 i = 0; i < materials.size(); i++) {
delete materials[i]; delete materials[i];
} }
delete[] materials;
} }
void Mesh::init() { void Mesh::init() {
id = rand() % 1000000; id = rand() % 1000000;
materialsCount = 0;
translation = M4x4::Identity; translation = M4x4::Identity;
rotation = M4x4::Identity; rotation = M4x4::Identity;
scale = M4x4::Identity; scale = M4x4::Identity;
+3 -3
View File
@@ -33,7 +33,7 @@ MeshFrame::MeshFrame(const MeshBuilderData& data, const u32& index) {
for (u32 i = 0; i < data.materials.size(); i++) delete bboxes[i]; for (u32 i = 0; i < data.materials.size(); i++) delete bboxes[i];
delete[] bboxes; delete[] bboxes;
_isMother = true; isMother = true;
} }
MeshFrame::MeshFrame(const MeshFrame& frame) { MeshFrame::MeshFrame(const MeshFrame& frame) {
@@ -41,11 +41,11 @@ MeshFrame::MeshFrame(const MeshFrame& frame) {
bbox = frame.bbox; bbox = frame.bbox;
_isMother = false; isMother = false;
} }
MeshFrame::~MeshFrame() { MeshFrame::~MeshFrame() {
if (_isMother) { if (isMother) {
delete bbox; delete bbox;
} }
} }
+21 -34
View File
@@ -30,70 +30,57 @@ MeshMaterial::MeshMaterial(const MeshBuilderData& data,
id = rand() % 1000000; id = rand() % 1000000;
if (data.lightMapEnabled) { if (data.lightMapEnabled) {
singleColorFlag = false; lightmapFlag = false;
TYRA_ASSERT(material->frames[0]->colors != nullptr, TYRA_ASSERT(material->frames[0]->colors != nullptr,
"Colors faces are required"); "Colors faces are required");
} else { } else {
singleColorFlag = true; lightmapFlag = true;
} }
color.set(material->ambient); ambient.set(material->ambient);
_name = material->name; name = material->name;
TYRA_ASSERT(_name.length() > 0, "MeshMaterial name cannot be empty"); TYRA_ASSERT(name.length() > 0, "MeshMaterial name cannot be empty");
framesCount = material->frames.size();
frames = new MeshMaterialFrame*[framesCount];
u32 lastVertexCount = 0; u32 lastVertexCount = 0;
for (u32 i = 0; i < framesCount; i++) { for (u32 i = 0; i < material->frames.size(); i++) {
frames[i] = new MeshMaterialFrame(data, i, materialIndex); frames.push_back(new MeshMaterialFrame(data, i, materialIndex));
if (i > 0) { if (i > 0) {
TYRA_ASSERT(frames[i]->getVertexCount() == lastVertexCount, TYRA_ASSERT(frames[i]->count == lastVertexCount,
"Vertex count must be the same for all frames"); "Vertex count must be the same for all frames");
} }
lastVertexCount = frames[i]->getVertexCount(); lastVertexCount = frames[i]->count;
} }
_isMother = true; isMother = true;
} }
MeshMaterial::MeshMaterial(const MeshMaterial& mesh) { MeshMaterial::MeshMaterial(const MeshMaterial& mesh) {
id = rand() % 1000000; id = rand() % 1000000;
singleColorFlag = mesh.singleColorFlag; lightmapFlag = mesh.lightmapFlag;
framesCount = mesh.framesCount; name = mesh.name;
_name = mesh._name;
color.set(128.0F, 128.0F, 128.0F, 128.0F); ambient.set(128.0F, 128.0F, 128.0F, 128.0F);
frames = new MeshMaterialFrame*[framesCount]; for (u32 i = 0; i < mesh.frames.size(); i++) {
for (u32 i = 0; i < framesCount; i++) { frames.push_back(new MeshMaterialFrame(*mesh.frames[i]));
frames[i] = new MeshMaterialFrame(*mesh.frames[i]);
} }
_isMother = false; isMother = false;
} }
MeshMaterial::~MeshMaterial() { MeshMaterial::~MeshMaterial() {
for (u32 i = 0; i < framesCount; i++) { for (u32 i = 0; i < frames.size(); i++) {
delete frames[i]; delete frames[i];
} }
delete[] frames;
} }
const BBox& MeshMaterial::getBBox(const u32& frame) const { const BBox& MeshMaterial::getBBox(const u32& frame) const {
return frames[frame]->getBBox(); return *frames[frame]->bbox;
}
void MeshMaterial::setSingleColorFlag(const u8& flag) {
TYRA_ASSERT(
frames[0]->getColors() != nullptr,
"Colors and color faces are required to use color-per-vertex mode");
singleColorFlag = flag;
} }
void MeshMaterial::print() const { void MeshMaterial::print() const {
@@ -117,9 +104,9 @@ std::string MeshMaterial::getPrint(const char* name) const {
res << std::endl; res << std::endl;
res << std::fixed << std::setprecision(2); res << std::fixed << std::setprecision(2);
res << "Id: " << id << ", " << std::endl; res << "Id: " << id << ", " << std::endl;
res << "Name: " << _name << ", " << std::endl; res << "Name: " << name << ", " << std::endl;
res << "Frames count: " << framesCount << ", " << std::endl; res << "Frames count: " << frames.size() << ", " << std::endl;
res << "Single color?: " << static_cast<u32>(singleColorFlag) << std::endl; res << "Single color?: " << static_cast<u32>(lightmapFlag) << std::endl;
res << ")"; res << ")";
return res.str(); return res.str();
@@ -44,11 +44,32 @@ MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data,
count = frame->count; count = frame->count;
vertices = frame->vertices; vertices = frame->vertices;
normals = frame->normals;
textureCoords = frame->textureCoords;
colors = frame->colors;
_isMother = true; if (data.normalsEnabled) {
normals = frame->normals;
} else {
if (frame->normals != nullptr) delete[] frame->normals;
normals = nullptr;
}
if (data.textureCoordsEnabled) {
textureCoords = frame->textureCoords;
} else {
if (frame->textureCoords != nullptr) delete[] frame->textureCoords;
textureCoords = nullptr;
}
if (data.lightMapEnabled) {
colors = frame->colors;
} else {
if (frame->colors != nullptr) delete[] frame->colors;
colors = nullptr;
}
isMother = true;
} }
MeshMaterialFrame::MeshMaterialFrame(const MeshMaterialFrame& frame) { MeshMaterialFrame::MeshMaterialFrame(const MeshMaterialFrame& frame) {
@@ -63,11 +84,11 @@ MeshMaterialFrame::MeshMaterialFrame(const MeshMaterialFrame& frame) {
bbox = frame.bbox; bbox = frame.bbox;
_isMother = false; isMother = false;
} }
MeshMaterialFrame::~MeshMaterialFrame() { MeshMaterialFrame::~MeshMaterialFrame() {
if (_isMother) { if (isMother) {
delete[] vertices; delete[] vertices;
if (normals) delete[] normals; if (normals) delete[] normals;
if (textureCoords) delete[] textureCoords; if (textureCoords) delete[] textureCoords;
@@ -62,8 +62,8 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
PipelineDirLightsBag* dirLights = nullptr; PipelineDirLightsBag* dirLights = nullptr;
if (options->frustumCulling == PipelineFrustumCulling_Simple) { if (options->frustumCulling == PipelineFrustumCulling_Simple) {
auto* frameTo = mesh->getFrame(mesh->getNextAnimationFrame()); auto* frameTo = mesh->frames[mesh->animState.nextFrame];
if (frameTo->getBBox().isInFrustum( if (frameTo->bbox->isInFrustum(
rendererCore->renderer3D.frustumPlanes.getAll(), model) == rendererCore->renderer3D.frustumPlanes.getAll(), model) ==
CoreBBoxFrustum::OUTSIDE_FRUSTUM) { CoreBBoxFrustum::OUTSIDE_FRUSTUM) {
return; return;
@@ -82,17 +82,15 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
setBuffersDefaultVars(buffers, mesh, infoBag); setBuffersDefaultVars(buffers, mesh, infoBag);
core.begin(infoBag); core.begin(infoBag);
for (u32 i = 0; i < mesh->getMaterialsCount(); i++) { for (u32 i = 0; i < mesh->materials.size(); i++) {
auto* material = mesh->getMaterial(i); auto* material = mesh->materials[i];
auto* frameFrom = material->getFrame(mesh->getCurrentAnimationFrame()); auto* frameFrom = material->frames[mesh->animState.currentFrame];
auto* frameTo = material->getFrame(mesh->getNextAnimationFrame()); auto* frameTo = material->frames[mesh->animState.nextFrame];
auto partSize = auto partSize = core.getMaxVertCountByParams(
core.getMaxVertCountByParams(options && options->lighting, options && options->lighting, material->frames[0]->textureCoords);
material->getFrame(0)->getTextureCoords());
u32 partsCount = u32 partsCount = ceil(frameFrom->count / static_cast<float>(partSize));
ceil(frameFrom->getVertexCount() / static_cast<float>(partSize));
auto* colorBag = getColorBag(material); auto* colorBag = getColorBag(material);
@@ -103,9 +101,8 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
auto& buffer = buffers[bufferIndex]; auto& buffer = buffers[bufferIndex];
freeBuffer(&buffer); freeBuffer(&buffer);
buffer.count = k == partsCount - 1 buffer.count =
? frameFrom->getVertexCount() - k * partSize k == partsCount - 1 ? frameFrom->count - k * partSize : partSize;
: partSize;
u32 startIndex = k * partSize; u32 startIndex = k * partSize;
@@ -183,7 +180,7 @@ void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers,
DynPipInfoBag* infoBag) { DynPipInfoBag* infoBag) {
for (u32 i = 0; i < buffersCount; i++) { for (u32 i = 0; i < buffersCount; i++) {
buffers[i].info = infoBag; buffers[i].info = infoBag;
buffers[i].interpolation = mesh->getAnimState().interpolation; buffers[i].interpolation = mesh->animState.interpolation;
} }
} }
@@ -226,31 +223,33 @@ DynPipInfoBag* DynamicPipeline::getInfoBag(DynamicMesh* mesh,
void DynamicPipeline::addVertices(MeshMaterialFrame* materialFrameFrom, void DynamicPipeline::addVertices(MeshMaterialFrame* materialFrameFrom,
MeshMaterialFrame* materialFrameTo, MeshMaterialFrame* materialFrameTo,
DynPipBag* bag, const u32& startIndex) const { DynPipBag* bag, const u32& startIndex) const {
bag->verticesFrom = &materialFrameFrom->getVertices()[startIndex]; bag->verticesFrom = &materialFrameFrom->vertices[startIndex];
bag->verticesTo = &materialFrameTo->getVertices()[startIndex]; bag->verticesTo = &materialFrameTo->vertices[startIndex];
} }
DynPipColorBag* DynamicPipeline::getColorBag(MeshMaterial* material) const { DynPipColorBag* DynamicPipeline::getColorBag(MeshMaterial* material) const {
auto* result = new DynPipColorBag(); auto* result = new DynPipColorBag();
result->single = &material->color; result->single = &material->ambient;
return result; return result;
} }
DynPipTextureBag* DynamicPipeline::getTextureBag( DynPipTextureBag* DynamicPipeline::getTextureBag(
MeshMaterial* material, MeshMaterialFrame* materialFrameFrom, MeshMaterial* material, MeshMaterialFrame* materialFrameFrom,
MeshMaterialFrame* materialFrameTo, const u32& startIndex) { MeshMaterialFrame* materialFrameTo, const u32& startIndex) {
if (!materialFrameFrom->getTextureCoords()) return nullptr; if (!materialFrameFrom->textureCoords) return nullptr;
auto* result = new DynPipTextureBag(); auto* result = new DynPipTextureBag();
result->texture = result->texture =
rendererCore->texture.repository.getBySpriteOrMesh(material->getId()); rendererCore->texture.repository.getBySpriteOrMesh(material->id);
TYRA_ASSERT(
result->texture, "Texture for material id: ", material->getId(),
"was not found in texture repository! Did you forget to add texture?");
result->coordinatesFrom = &materialFrameFrom->getTextureCoords()[startIndex]; TYRA_ASSERT(
result->coordinatesTo = &materialFrameTo->getTextureCoords()[startIndex]; result->texture, "Texture for material: ", material->name,
"Id: ", material->id,
"Was not found in texture repository! Did you forget to add texture?");
result->coordinatesFrom = &materialFrameFrom->textureCoords[startIndex];
result->coordinatesTo = &materialFrameTo->textureCoords[startIndex];
return result; return result;
} }
@@ -259,7 +258,7 @@ DynPipLightingBag* DynamicPipeline::getLightingBag(
MeshMaterialFrame* materialFrameFrom, MeshMaterialFrame* materialFrameTo, MeshMaterialFrame* materialFrameFrom, MeshMaterialFrame* materialFrameTo,
M4x4* model, const DynPipOptions* options, M4x4* model, const DynPipOptions* options,
PipelineDirLightsBag* dirLightsBag, const u32& startIndex) const { PipelineDirLightsBag* dirLightsBag, const u32& startIndex) const {
if (!materialFrameFrom->getNormals() || options == nullptr || if (!materialFrameFrom->normals || options == nullptr ||
options->lighting == nullptr) options->lighting == nullptr)
return nullptr; return nullptr;
@@ -268,8 +267,8 @@ DynPipLightingBag* DynamicPipeline::getLightingBag(
result->lightMatrix = model; result->lightMatrix = model;
result->dirLights = dirLightsBag; result->dirLights = dirLightsBag;
result->normalsFrom = &materialFrameFrom->getNormals()[startIndex]; result->normalsFrom = &materialFrameFrom->normals[startIndex];
result->normalsTo = &materialFrameTo->getNormals()[startIndex]; result->normalsTo = &materialFrameTo->normals[startIndex];
return result; return result;
} }
@@ -59,8 +59,8 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) {
"matrix!"); "matrix!");
if (options->frustumCulling == PipelineFrustumCulling_Simple) { if (options->frustumCulling == PipelineFrustumCulling_Simple) {
auto* frame = mesh->getFrame(); auto* frame = mesh->frame;
if (frame->getBBox().isInFrustum( if (frame->bbox->isInFrustum(
rendererCore->renderer3D.frustumPlanes.getAll(), model) == rendererCore->renderer3D.frustumPlanes.getAll(), model) ==
CoreBBoxFrustum::OUTSIDE_FRUSTUM) { CoreBBoxFrustum::OUTSIDE_FRUSTUM) {
return; return;
@@ -69,9 +69,9 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) {
if (options && options->lighting) setLightingColorsCache(options->lighting); if (options && options->lighting) setLightingColorsCache(options->lighting);
for (u32 i = 0; i < mesh->getMaterialsCount(); i++) { for (u32 i = 0; i < mesh->materials.size(); i++) {
auto* material = mesh->getMaterial(i); auto* material = mesh->materials[i];
auto* materialFrame = material->getFrame(0); auto* materialFrame = material->frames[0];
StaPipBag bag; StaPipBag bag;
addVertices(materialFrame, &bag); addVertices(materialFrame, &bag);
bag.info = infoBag; bag.info = infoBag;
@@ -89,8 +89,8 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) {
void StaticPipeline::addVertices(MeshMaterialFrame* materialFrame, void StaticPipeline::addVertices(MeshMaterialFrame* materialFrame,
StaPipBag* bag) const { StaPipBag* bag) const {
bag->count = materialFrame->getVertexCount(); bag->count = materialFrame->count;
bag->vertices = materialFrame->getVertices(); bag->vertices = materialFrame->vertices;
} }
StaPipInfoBag* StaticPipeline::getInfoBag(StaticMesh* mesh, StaPipInfoBag* StaticPipeline::getInfoBag(StaticMesh* mesh,
@@ -118,10 +118,10 @@ StaPipColorBag* StaticPipeline::getColorBag(
MeshMaterial* material, MeshMaterialFrame* materialFrame) const { MeshMaterial* material, MeshMaterialFrame* materialFrame) const {
auto* result = new StaPipColorBag(); auto* result = new StaPipColorBag();
if (material->isSingleColorActivated()) { if (material->lightmapFlag) {
result->single = &material->color; result->single = &material->ambient;
} else { } else {
result->many = materialFrame->getColors(); result->many = materialFrame->colors;
} }
return result; return result;
@@ -129,17 +129,19 @@ StaPipColorBag* StaticPipeline::getColorBag(
StaPipTextureBag* StaticPipeline::getTextureBag( StaPipTextureBag* StaticPipeline::getTextureBag(
MeshMaterial* material, MeshMaterialFrame* materialFrame) { MeshMaterial* material, MeshMaterialFrame* materialFrame) {
if (!materialFrame->getTextureCoords()) return nullptr; if (!materialFrame->textureCoords) return nullptr;
auto* result = new StaPipTextureBag(); auto* result = new StaPipTextureBag();
result->texture = result->texture =
rendererCore->texture.repository.getBySpriteOrMesh(material->getId()); rendererCore->texture.repository.getBySpriteOrMesh(material->id);
TYRA_ASSERT(
result->texture, "Texture for material id: ", material->getId(),
"was not found in texture repository! Did you forget to add texture?");
result->coordinates = materialFrame->getTextureCoords(); TYRA_ASSERT(
result->texture, "Texture for material: ", material->name,
"Id: ", material->id,
"Was not found in texture repository! Did you forget to add texture?");
result->coordinates = materialFrame->textureCoords;
return result; return result;
} }
@@ -147,13 +149,14 @@ StaPipTextureBag* StaticPipeline::getTextureBag(
StaPipLightingBag* StaticPipeline::getLightingBag( StaPipLightingBag* StaticPipeline::getLightingBag(
MeshMaterialFrame* materialFrame, M4x4* model, MeshMaterialFrame* materialFrame, M4x4* model,
const StaPipOptions* options) const { const StaPipOptions* options) const {
if (!materialFrame->getNormals() || options == nullptr || if (!materialFrame->normals || options == nullptr ||
options->lighting == nullptr) options->lighting == nullptr)
return nullptr; return nullptr;
auto* result = new StaPipLightingBag(); auto* result = new StaPipLightingBag();
auto* dirLightsBag = new PipelineDirLightsBag(true); // TODO: 1 dir
// lights per obiekt, dealokowac recznie // TODO: Make it once per rendering, very redundant
auto* dirLightsBag = new PipelineDirLightsBag(true);
result->dirLights = dirLightsBag; result->dirLights = dirLightsBag;
result->lightMatrix = model; result->lightMatrix = model;
@@ -161,7 +164,7 @@ StaPipLightingBag* StaticPipeline::getLightingBag(
result->dirLights->setLightsManually( result->dirLights->setLightsManually(
colorsCache, options->lighting->directionalDirections); colorsCache, options->lighting->directionalDirections);
result->normals = materialFrame->getNormals(); result->normals = materialFrame->normals;
return result; return result;
} }
+62 -62
View File
@@ -17,71 +17,71 @@ namespace Tyra {
CoreBBox::CoreBBox() { CoreBBox::CoreBBox() {
for (u32 i = 0; i < 8; i++) { for (u32 i = 0; i < 8; i++) {
_vertices[i] = Vec4(0.0F, 0.0F, 0.0F, 1.0F); vertices[i] = Vec4(0.0F, 0.0F, 0.0F, 1.0F);
} }
} }
CoreBBox::CoreBBox(CoreBBox** t_bboxes, const u32& count) { CoreBBox::CoreBBox(CoreBBox** t_bboxes, const u32& count) {
float lowX = t_bboxes[0]->_vertices[0].x; float lowX = t_bboxes[0]->vertices[0].x;
float lowY = t_bboxes[0]->_vertices[0].y; float lowY = t_bboxes[0]->vertices[0].y;
float lowZ = t_bboxes[0]->_vertices[0].z; float lowZ = t_bboxes[0]->vertices[0].z;
float hiX = t_bboxes[0]->_vertices[7].x; float hiX = t_bboxes[0]->vertices[7].x;
float hiY = t_bboxes[0]->_vertices[7].y; float hiY = t_bboxes[0]->vertices[7].y;
float hiZ = t_bboxes[0]->_vertices[7].z; float hiZ = t_bboxes[0]->vertices[7].z;
for (u32 i = 0; i < count; i++) { for (u32 i = 0; i < count; i++) {
if (lowX > t_bboxes[i]->_vertices[0].x) lowX = t_bboxes[i]->_vertices[0].x; if (lowX > t_bboxes[i]->vertices[0].x) lowX = t_bboxes[i]->vertices[0].x;
if (hiX < t_bboxes[i]->_vertices[7].x) hiX = t_bboxes[i]->_vertices[7].x; if (hiX < t_bboxes[i]->vertices[7].x) hiX = t_bboxes[i]->vertices[7].x;
if (lowY > t_bboxes[i]->_vertices[0].y) lowY = t_bboxes[i]->_vertices[0].y; if (lowY > t_bboxes[i]->vertices[0].y) lowY = t_bboxes[i]->vertices[0].y;
if (hiY < t_bboxes[i]->_vertices[7].y) hiY = t_bboxes[i]->_vertices[7].y; if (hiY < t_bboxes[i]->vertices[7].y) hiY = t_bboxes[i]->vertices[7].y;
if (lowZ > t_bboxes[i]->_vertices[0].z) lowZ = t_bboxes[i]->_vertices[0].z; if (lowZ > t_bboxes[i]->vertices[0].z) lowZ = t_bboxes[i]->vertices[0].z;
if (hiZ < t_bboxes[i]->_vertices[7].z) hiZ = t_bboxes[i]->_vertices[7].z; if (hiZ < t_bboxes[i]->vertices[7].z) hiZ = t_bboxes[i]->vertices[7].z;
} }
_vertices[0].set(lowX, lowY, lowZ); vertices[0].set(lowX, lowY, lowZ);
_vertices[1].set(lowX, lowY, hiZ); vertices[1].set(lowX, lowY, hiZ);
_vertices[2].set(lowX, hiY, lowZ); vertices[2].set(lowX, hiY, lowZ);
_vertices[3].set(lowX, hiY, hiZ); vertices[3].set(lowX, hiY, hiZ);
_vertices[4].set(hiX, lowY, lowZ); vertices[4].set(hiX, lowY, lowZ);
_vertices[5].set(hiX, lowY, hiZ); vertices[5].set(hiX, lowY, hiZ);
_vertices[6].set(hiX, hiY, lowZ); vertices[6].set(hiX, hiY, lowZ);
_vertices[7].set(hiX, hiY, hiZ); vertices[7].set(hiX, hiY, hiZ);
} }
CoreBBox::CoreBBox(const std::vector<CoreBBox>& t_bboxes, const u32& startIndex, CoreBBox::CoreBBox(const std::vector<CoreBBox>& t_bboxes, const u32& startIndex,
const u32& stopIndex) { const u32& stopIndex) {
float lowX = t_bboxes[startIndex]._vertices[0].x; float lowX = t_bboxes[startIndex].vertices[0].x;
float lowY = t_bboxes[startIndex]._vertices[0].y; float lowY = t_bboxes[startIndex].vertices[0].y;
float lowZ = t_bboxes[startIndex]._vertices[0].z; float lowZ = t_bboxes[startIndex].vertices[0].z;
float hiX = t_bboxes[startIndex]._vertices[7].x; float hiX = t_bboxes[startIndex].vertices[7].x;
float hiY = t_bboxes[startIndex]._vertices[7].y; float hiY = t_bboxes[startIndex].vertices[7].y;
float hiZ = t_bboxes[startIndex]._vertices[7].z; float hiZ = t_bboxes[startIndex].vertices[7].z;
for (u32 i = startIndex; i < stopIndex; i++) { for (u32 i = startIndex; i < stopIndex; i++) {
if (lowX > t_bboxes[i]._vertices[0].x) lowX = t_bboxes[i]._vertices[0].x; if (lowX > t_bboxes[i].vertices[0].x) lowX = t_bboxes[i].vertices[0].x;
if (hiX < t_bboxes[i]._vertices[7].x) hiX = t_bboxes[i]._vertices[7].x; if (hiX < t_bboxes[i].vertices[7].x) hiX = t_bboxes[i].vertices[7].x;
if (lowY > t_bboxes[i]._vertices[0].y) lowY = t_bboxes[i]._vertices[0].y; if (lowY > t_bboxes[i].vertices[0].y) lowY = t_bboxes[i].vertices[0].y;
if (hiY < t_bboxes[i]._vertices[7].y) hiY = t_bboxes[i]._vertices[7].y; if (hiY < t_bboxes[i].vertices[7].y) hiY = t_bboxes[i].vertices[7].y;
if (lowZ > t_bboxes[i]._vertices[0].z) lowZ = t_bboxes[i]._vertices[0].z; if (lowZ > t_bboxes[i].vertices[0].z) lowZ = t_bboxes[i].vertices[0].z;
if (hiZ < t_bboxes[i]._vertices[7].z) hiZ = t_bboxes[i]._vertices[7].z; if (hiZ < t_bboxes[i].vertices[7].z) hiZ = t_bboxes[i].vertices[7].z;
} }
_vertices[0].set(lowX, lowY, lowZ); vertices[0].set(lowX, lowY, lowZ);
_vertices[1].set(lowX, lowY, hiZ); vertices[1].set(lowX, lowY, hiZ);
_vertices[2].set(lowX, hiY, lowZ); vertices[2].set(lowX, hiY, lowZ);
_vertices[3].set(lowX, hiY, hiZ); vertices[3].set(lowX, hiY, hiZ);
_vertices[4].set(hiX, lowY, lowZ); vertices[4].set(hiX, lowY, lowZ);
_vertices[5].set(hiX, lowY, hiZ); vertices[5].set(hiX, lowY, hiZ);
_vertices[6].set(hiX, hiY, lowZ); vertices[6].set(hiX, hiY, lowZ);
_vertices[7].set(hiX, hiY, hiZ); vertices[7].set(hiX, hiY, hiZ);
} }
CoreBBox::CoreBBox(Vec4* t_vertices, u32* faces, u32 count) { CoreBBox::CoreBBox(Vec4* t_vertices, u32* faces, u32 count) {
@@ -100,15 +100,15 @@ CoreBBox::CoreBBox(Vec4* t_vertices, u32* faces, u32 count) {
if (hiZ < t_vertices[faces[i]].z) hiZ = t_vertices[faces[i]].z; if (hiZ < t_vertices[faces[i]].z) hiZ = t_vertices[faces[i]].z;
} }
_vertices[0].set(lowX, lowY, lowZ); vertices[0].set(lowX, lowY, lowZ);
_vertices[1].set(lowX, lowY, hiZ); vertices[1].set(lowX, lowY, hiZ);
_vertices[2].set(lowX, hiY, lowZ); vertices[2].set(lowX, hiY, lowZ);
_vertices[3].set(lowX, hiY, hiZ); vertices[3].set(lowX, hiY, hiZ);
_vertices[4].set(hiX, lowY, lowZ); vertices[4].set(hiX, lowY, lowZ);
_vertices[5].set(hiX, lowY, hiZ); vertices[5].set(hiX, lowY, hiZ);
_vertices[6].set(hiX, hiY, lowZ); vertices[6].set(hiX, hiY, lowZ);
_vertices[7].set(hiX, hiY, hiZ); vertices[7].set(hiX, hiY, hiZ);
} }
CoreBBox::CoreBBox(Vec4* t_vertices, u32 count) { CoreBBox::CoreBBox(Vec4* t_vertices, u32 count) {
@@ -127,24 +127,24 @@ CoreBBox::CoreBBox(Vec4* t_vertices, u32 count) {
if (hiZ < t_vertices[i].z) hiZ = t_vertices[i].z; if (hiZ < t_vertices[i].z) hiZ = t_vertices[i].z;
} }
_vertices[0].set(lowX, lowY, lowZ); vertices[0].set(lowX, lowY, lowZ);
_vertices[1].set(lowX, lowY, hiZ); vertices[1].set(lowX, lowY, hiZ);
_vertices[2].set(lowX, hiY, lowZ); vertices[2].set(lowX, hiY, lowZ);
_vertices[3].set(lowX, hiY, hiZ); vertices[3].set(lowX, hiY, hiZ);
_vertices[4].set(hiX, lowY, lowZ); vertices[4].set(hiX, lowY, lowZ);
_vertices[5].set(hiX, lowY, hiZ); vertices[5].set(hiX, lowY, hiZ);
_vertices[6].set(hiX, hiY, lowZ); vertices[6].set(hiX, hiY, lowZ);
_vertices[7].set(hiX, hiY, hiZ); vertices[7].set(hiX, hiY, hiZ);
} }
CoreBBox::CoreBBox(const CoreBBox& t_bbox) { CoreBBox::CoreBBox(const CoreBBox& t_bbox) {
for (auto i = 0; i < 8; i++) for (auto i = 0; i < 8; i++)
Vec4::copy(&_vertices[i], t_bbox._vertices[i].xyzw); Vec4::copy(&vertices[i], t_bbox.vertices[i].xyzw);
} }
CoreBBox::CoreBBox(Vec4* t_vertices) { CoreBBox::CoreBBox(Vec4* t_vertices) {
for (auto i = 0; i < 8; i++) Vec4::copy(&_vertices[i], t_vertices[i].xyzw); for (auto i = 0; i < 8; i++) Vec4::copy(&vertices[i], t_vertices[i].xyzw);
} }
void CoreBBox::print() const { void CoreBBox::print() const {
@@ -167,8 +167,8 @@ std::string CoreBBox::getPrint(const char* name) const {
res << std::fixed << std::setprecision(4); res << std::fixed << std::setprecision(4);
res << std::endl; res << std::endl;
for (auto i = 0; i < 8; i++) { for (auto i = 0; i < 8; i++) {
res << i << ": " << _vertices[i].x << ", " << _vertices[i].y << ", " res << i << ": " << vertices[i].x << ", " << vertices[i].y << ", "
<< _vertices[i].z << ", " << _vertices[i].w; << vertices[i].z << ", " << vertices[i].w;
if (i != 7) if (i != 7)
res << std::endl; res << std::endl;
@@ -194,7 +194,7 @@ CoreBBoxFrustum CoreBBox::isInFrustum(const Plane* frustumPlanes,
// get out of the cycle as soon as a box as corners // get out of the cycle as soon as a box as corners
// both inside and out of the frustum // both inside and out of the frustum
for (u8 y = 0; y < 8 && (boxIn == 0 || boxOut == 0); y++) { for (u8 y = 0; y < 8 && (boxIn == 0 || boxOut == 0); y++) {
boxCalcTemp = model * _vertices[y]; boxCalcTemp = model * vertices[y];
auto isOut = frustumPlanes[i].distanceTo(boxCalcTemp) <= margin; auto isOut = frustumPlanes[i].distanceTo(boxCalcTemp) <= margin;
@@ -84,15 +84,15 @@ void TextureRepository::addByMesh(Mesh* mesh, const char* directory,
std::string dirFixed = directory; std::string dirFixed = directory;
if (dirFixed.back() != '/' && dirFixed.back() != ':') dirFixed += "/"; if (dirFixed.back() != '/' && dirFixed.back() != ':') dirFixed += "/";
for (u32 i = 0; i < mesh->getMaterialsCount(); i++) { for (u32 i = 0; i < mesh->materials.size(); i++) {
std::string fullPath = std::string fullPath =
dirFixed + mesh->getMaterial(i)->getName() + "." + extension; dirFixed + mesh->materials[i]->name + "." + extension;
auto* data = loader.load(fullPath.c_str()); auto* data = loader.load(fullPath.c_str());
Texture* texture = new Texture(data); Texture* texture = new Texture(data);
delete data; delete data;
texture->addLink(mesh->getMaterial(i)->getId()); texture->addLink(mesh->materials[i]->id);
textures.push_back(texture); textures.push_back(texture);
} }
} }
+14 -9
View File
@@ -55,7 +55,7 @@ void Tutorial01 ::init() {
warrior = getWarrior(&engine->renderer); warrior = getWarrior(&engine->renderer);
warriorTex = engine->renderer.core.texture.repository.getBySpriteOrMesh( warriorTex = engine->renderer.core.texture.repository.getBySpriteOrMesh(
warrior->getMaterial(0)->getId()); warrior->materials[0]->id);
warriorsCount = 22; warriorsCount = 22;
warriors = new DynamicMesh*[warriorsCount]; warriors = new DynamicMesh*[warriorsCount];
@@ -65,10 +65,10 @@ void Tutorial01 ::init() {
warriors[i]->translation.translateY(30.0F); warriors[i]->translation.translateY(30.0F);
warriors[i]->translation.translateZ(-10.0F); warriors[i]->translation.translateZ(-10.0F);
warriors[i]->translation.rotateX(-1.5F); warriors[i]->translation.rotateX(-1.5F);
warriorTex->addLink(warriors[i]->getMaterial(0)->getId()); warriorTex->addLink(warriors[i]->materials[0]->id);
warriors[i]->playAnimation(0, warriors[i]->getFramesCount() - 1); warriors[i]->playAnimation(0, warriors[i]->frames.size() - 1);
warriors[i]->setCurrentAnimationFrame( warriors[i]->animState.currentFrame =
getRandomInt(0, warriors[i]->getFramesCount() - 1)); getRandomInt(0, warriors[i]->frames.size() - 1);
warriors[i]->setAnimSpeed(getRandomFloat(0.1F, 0.9F)); warriors[i]->setAnimSpeed(getRandomFloat(0.1F, 0.9F));
} }
@@ -194,7 +194,10 @@ void Tutorial01 ::loop() {
StaticMesh* getStaticMesh(Renderer* renderer) { StaticMesh* getStaticMesh(Renderer* renderer) {
MD2Loader loader; MD2Loader loader;
auto* data = loader.load(FileUtils::fromCwd("warrior.md2"), .08F, false); MD2LoaderOptions options;
options.scale = .08F;
auto* data = loader.load(FileUtils::fromCwd("warrior.md2"), options);
auto* result = new StaticMesh(*data); auto* result = new StaticMesh(*data);
// result->translation.translateZ(-30.0F); // result->translation.translateZ(-30.0F);
delete data; delete data;
@@ -223,7 +226,9 @@ StaticMesh* getSkybox(Renderer* renderer) {
DynamicMesh* getWarrior(Renderer* renderer) { DynamicMesh* getWarrior(Renderer* renderer) {
MD2Loader loader; MD2Loader loader;
auto* data = loader.load(FileUtils::fromCwd("warrior.md2"), .08F, false); MD2LoaderOptions options;
options.scale = .08F;
auto* data = loader.load(FileUtils::fromCwd("warrior.md2"), options);
auto* result = new DynamicMesh(*data); auto* result = new DynamicMesh(*data);
// result->translation.translateZ(-30.0F); // result->translation.translateZ(-30.0F);
delete data; delete data;
@@ -231,7 +236,7 @@ DynamicMesh* getWarrior(Renderer* renderer) {
renderer->core.texture.repository.addByMesh(result, FileUtils::getCwd(), renderer->core.texture.repository.addByMesh(result, FileUtils::getCwd(),
"png"); "png");
result->playAnimation(0, result->getFramesCount() - 1); result->playAnimation(0, result->frames.size() - 1);
result->setAnimSpeed(0.15F); result->setAnimSpeed(0.15F);
return result; return result;
@@ -248,7 +253,7 @@ DynamicMesh* getCube(Renderer* renderer) {
result->translation.translateZ(-30.0F); result->translation.translateZ(-30.0F);
delete data; delete data;
result->playAnimation(0, result->getFramesCount() - 1); result->playAnimation(0, result->frames.size() - 1);
result->setAnimSpeed(0.15F); result->setAnimSpeed(0.15F);
return result; return result;