mesh refactor 3
This commit is contained in:
+4
-11
@@ -1,18 +1,9 @@
|
||||
------------ 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] 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
|
||||
|
||||
|
||||
@@ -40,6 +31,8 @@ because Mesh rendering uses only core.render()
|
||||
- [General] Credits: clipping, obj loader
|
||||
|
||||
------------ Github issues for Tyra v2 ------------
|
||||
- [rendere] fog
|
||||
- [rendere] bbox parts optimization
|
||||
- [md2] refactor
|
||||
- [3D] Add drawLine(x, y , color, size)
|
||||
- [2D] Fixed font support
|
||||
|
||||
@@ -15,18 +15,24 @@
|
||||
using Tyra::Color;
|
||||
using Tyra::FileUtils;
|
||||
using Tyra::ObjLoader;
|
||||
using Tyra::ObjLoaderOptions;
|
||||
|
||||
namespace Demo {
|
||||
|
||||
DebugObject::DebugObject(TextureRepository* repo) {
|
||||
ObjLoader loader;
|
||||
|
||||
ObjLoaderOptions objOptions;
|
||||
objOptions.flipUVs = true;
|
||||
objOptions.scale = .5F;
|
||||
|
||||
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->textureCoordsEnabled = false;
|
||||
mesh = new StaticMesh(*data);
|
||||
delete data;
|
||||
mesh->getMaterial(0)->color = Color(192.0F, 32.0F, 32.0F, 128.0F);
|
||||
|
||||
rotator = 0.0F;
|
||||
allocateOptions();
|
||||
|
||||
|
||||
@@ -14,20 +14,26 @@
|
||||
|
||||
using Tyra::FileUtils;
|
||||
using Tyra::ObjLoader;
|
||||
using Tyra::ObjLoaderOptions;
|
||||
|
||||
namespace Demo {
|
||||
|
||||
Enemy::Enemy(TextureRepository* repo) {
|
||||
ObjLoader loader;
|
||||
|
||||
ObjLoaderOptions objOptions;
|
||||
objOptions.animation.count = 4;
|
||||
objOptions.flipUVs = true;
|
||||
objOptions.scale = 25.0F;
|
||||
|
||||
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;
|
||||
bodyMesh = new DynamicMesh(*bodyData);
|
||||
|
||||
delete bodyData;
|
||||
|
||||
bodyMesh->playAnimation(0, bodyMesh->getFramesCount() - 1);
|
||||
bodyMesh->playAnimation(0, bodyMesh->frames.size() - 1);
|
||||
bodyMesh->setAnimSpeed(0.1F);
|
||||
|
||||
repo->addByMesh(bodyMesh, FileUtils::fromCwd("game/models/soldier/"), "png");
|
||||
|
||||
@@ -14,21 +14,23 @@
|
||||
|
||||
using Tyra::FileUtils;
|
||||
using Tyra::ObjLoader;
|
||||
using Tyra::ObjLoaderOptions;
|
||||
|
||||
namespace Demo {
|
||||
|
||||
Weapon::Weapon(TextureRepository* repo) {
|
||||
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;
|
||||
mesh = new StaticMesh(*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.translateY(-3.40F);
|
||||
mesh->translation.translateZ(-10.50F);
|
||||
|
||||
@@ -14,24 +14,23 @@
|
||||
|
||||
using Tyra::FileUtils;
|
||||
using Tyra::ObjLoader;
|
||||
using Tyra::ObjLoaderOptions;
|
||||
|
||||
namespace Demo {
|
||||
|
||||
Skybox::Skybox(TextureRepository* repo) {
|
||||
ObjLoader loader;
|
||||
|
||||
ObjLoaderOptions objOptions;
|
||||
objOptions.flipUVs = true;
|
||||
objOptions.scale = 100.0F;
|
||||
|
||||
auto* data = loader.load(FileUtils::fromCwd("game/models/skybox/skybox.obj"),
|
||||
1, 100.0F, true);
|
||||
objOptions);
|
||||
data->normalsEnabled = false;
|
||||
mesh = new StaticMesh(*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");
|
||||
|
||||
allocateOptions();
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
using Tyra::FileUtils;
|
||||
using Tyra::ObjLoader;
|
||||
using Tyra::ObjLoaderOptions;
|
||||
|
||||
namespace Demo {
|
||||
Terrain::Terrain(TextureRepository* repo)
|
||||
@@ -23,13 +24,16 @@ Terrain::Terrain(TextureRepository* repo)
|
||||
Vec4(286.0F, 0.0F, 443.3F, 1.0F) // Right down
|
||||
) {
|
||||
ObjLoader loader;
|
||||
|
||||
ObjLoaderOptions objOptions;
|
||||
objOptions.flipUVs = true;
|
||||
objOptions.scale = 25.0F;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
repo->addByMesh(mesh, FileUtils::fromCwd("game/models/terrain/"), "png");
|
||||
|
||||
@@ -16,19 +16,21 @@
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
struct MD2LoaderOptions {
|
||||
bool flipUVs = false;
|
||||
float scale = 1.0F;
|
||||
};
|
||||
|
||||
/** Class responsible for loading & parsing Quake's II ".md2" 3D files */
|
||||
class MD2Loader : public Loader {
|
||||
public:
|
||||
MD2Loader();
|
||||
~MD2Loader();
|
||||
|
||||
MeshBuilderData* load(const char* fullpath, const float& scale,
|
||||
const bool& invertT);
|
||||
|
||||
inline MeshBuilderData* load(const std::string& fullpath, const float& scale,
|
||||
const bool& invertT) {
|
||||
return load(fullpath.c_str(), scale, invertT);
|
||||
}
|
||||
MeshBuilderData* load(const char* fullpath);
|
||||
MeshBuilderData* load(const char* fullpath, MD2LoaderOptions options);
|
||||
MeshBuilderData* load(const std::string& fullpath);
|
||||
MeshBuilderData* load(const std::string& fullpath, MD2LoaderOptions options);
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
@@ -23,35 +23,17 @@ class DynamicMesh : public Mesh {
|
||||
explicit DynamicMesh(const DynamicMesh& mesh);
|
||||
~DynamicMesh();
|
||||
|
||||
const DynamicMeshAnimState& getAnimState() const { return animState; }
|
||||
std::vector<MeshFrame*> frames;
|
||||
|
||||
/** Returns single frame. */
|
||||
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; }
|
||||
DynamicMeshAnimState animState;
|
||||
|
||||
/** @returns bounding box object of current frame. */
|
||||
const BBox& getCurrentBoundingBox() const {
|
||||
return frames[animState.currentFrame]->getBBox();
|
||||
return *frames[animState.currentFrame]->bbox;
|
||||
}
|
||||
|
||||
/** 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 */
|
||||
void playAnimation(const u32& t_startFrame, const u32& t_endFrame);
|
||||
@@ -73,9 +55,6 @@ class DynamicMesh : public Mesh {
|
||||
|
||||
private:
|
||||
void initAnimation();
|
||||
DynamicMeshAnimState animState;
|
||||
u32 framesCount;
|
||||
MeshFrame** frames;
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
@@ -23,17 +23,14 @@ class Mesh {
|
||||
explicit Mesh(const Mesh& mesh);
|
||||
~Mesh();
|
||||
|
||||
/** Translation matrix */
|
||||
M4x4 translation;
|
||||
u8 isMother;
|
||||
|
||||
/** Rotation matrix */
|
||||
M4x4 rotation;
|
||||
u32 id;
|
||||
|
||||
/** Scale matrix */
|
||||
M4x4 scale;
|
||||
M4x4 translation, rotation, scale;
|
||||
|
||||
std::vector<MeshMaterial*> materials;
|
||||
|
||||
inline const u32& getId() const { return id; }
|
||||
inline const u8& isMother() const { return _isMother; }
|
||||
M4x4 getModelMatrix() const;
|
||||
|
||||
/** Get position from translation matrix */
|
||||
@@ -43,18 +40,8 @@ class Mesh {
|
||||
|
||||
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:
|
||||
void init();
|
||||
u8 _isMother;
|
||||
u32 id, materialsCount;
|
||||
MeshMaterial** materials;
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
@@ -22,19 +22,16 @@ class MeshFrame {
|
||||
explicit MeshFrame(const MeshFrame& frame);
|
||||
~MeshFrame();
|
||||
|
||||
const u32& getId() const { return id; }
|
||||
const u8& isMother() const { return _isMother; }
|
||||
const BBox& getBBox() const { return *bbox; }
|
||||
u8 isMother;
|
||||
|
||||
u32 id;
|
||||
|
||||
BBox* bbox;
|
||||
|
||||
void print() const;
|
||||
void print(const char* name) const;
|
||||
void print(const std::string& name) const { print(name.c_str()); }
|
||||
std::string getPrint(const char* name = nullptr) const;
|
||||
|
||||
private:
|
||||
u8 _isMother;
|
||||
BBox* bbox;
|
||||
u32 id;
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
@@ -22,33 +22,22 @@ class MeshMaterial {
|
||||
explicit MeshMaterial(const MeshMaterial& material);
|
||||
~MeshMaterial();
|
||||
|
||||
Color color;
|
||||
u8 isMother, lightmapFlag;
|
||||
|
||||
const u32& getId() const { return 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
|
||||
u32 id;
|
||||
|
||||
MeshMaterialFrame** getFrames() const { return frames; }
|
||||
MeshMaterialFrame* getFrame(const u32& i) const { return frames[i]; }
|
||||
std::string name;
|
||||
|
||||
Color ambient;
|
||||
|
||||
std::vector<MeshMaterialFrame*> frames;
|
||||
|
||||
const BBox& getBBox(const u32& frame) const;
|
||||
void setSingleColorFlag(const u8& flag);
|
||||
|
||||
void print() const;
|
||||
void print(const char* name) const;
|
||||
void print(const std::string& name) const { print(name.c_str()); }
|
||||
std::string getPrint(const char* name = nullptr) const;
|
||||
|
||||
private:
|
||||
MeshMaterialFrame** frames;
|
||||
|
||||
std::string _name;
|
||||
u8 _isMother, singleColorFlag;
|
||||
u32 id, framesCount;
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
@@ -22,28 +22,20 @@ class MeshMaterialFrame {
|
||||
explicit MeshMaterialFrame(const MeshMaterialFrame& frame);
|
||||
~MeshMaterialFrame();
|
||||
|
||||
const u32& getId() const { return id; }
|
||||
const u8& isMother() const { return _isMother; }
|
||||
const BBox& getBBox() const { return *bbox; }
|
||||
u8 isMother;
|
||||
|
||||
const u32& getVertexCount() const { return count; }
|
||||
Vec4* getVertices() const { return vertices; }
|
||||
Vec4* getNormals() const { return normals; }
|
||||
Vec4* getTextureCoords() const { return textureCoords; }
|
||||
Color* getColors() const { return colors; }
|
||||
u32 id, count;
|
||||
|
||||
Vec4 *vertices, *textureCoords, *normals;
|
||||
|
||||
Color* colors;
|
||||
|
||||
BBox* bbox;
|
||||
|
||||
void print() const;
|
||||
void print(const char* name) const;
|
||||
void print(const std::string& name) const { print(name.c_str()); }
|
||||
std::string getPrint(const char* name = nullptr) const;
|
||||
|
||||
private:
|
||||
BBox* bbox;
|
||||
|
||||
u8 _isMother;
|
||||
u32 id, count;
|
||||
Vec4 *vertices, *textureCoords, *normals;
|
||||
Color* colors;
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
@@ -22,12 +22,6 @@ class StaticMesh : public Mesh {
|
||||
StaticMesh(const StaticMesh& mesh);
|
||||
~StaticMesh();
|
||||
|
||||
MeshFrame* getFrame() { return frame; }
|
||||
|
||||
/** @returns bounding box object of current frame. */
|
||||
const BBox& getBoundingBox() const { return frame->getBBox(); }
|
||||
|
||||
private:
|
||||
MeshFrame* frame;
|
||||
};
|
||||
|
||||
|
||||
@@ -30,10 +30,11 @@ class CoreBBox {
|
||||
explicit CoreBBox(const std::vector<CoreBBox>& t_bboxes,
|
||||
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 Vec4& getVertex(const u8& i) { return _vertices[i]; }
|
||||
Vec4* getVertices() { return _vertices; }
|
||||
|
||||
void print() const;
|
||||
void print(const char* name) const;
|
||||
@@ -42,9 +43,6 @@ class CoreBBox {
|
||||
|
||||
CoreBBoxFrustum isInFrustum(const Plane* frustumPlanes, const M4x4& model,
|
||||
const float* margins = nullptr) const;
|
||||
|
||||
protected:
|
||||
Vec4 _vertices[8];
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
@@ -74,8 +74,21 @@ MD2Loader::MD2Loader() {}
|
||||
|
||||
MD2Loader::~MD2Loader() {}
|
||||
|
||||
MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale,
|
||||
const bool& invertT) {
|
||||
MeshBuilderData* MD2Loader::load(const char* fullpath) {
|
||||
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;
|
||||
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++) {
|
||||
temp.set(((frame->verts[vertexIndex].v[0] * frame->scale[0]) +
|
||||
frame->translate[0]) *
|
||||
scale,
|
||||
options.scale,
|
||||
((frame->verts[vertexIndex].v[1] * frame->scale[1]) +
|
||||
frame->translate[1]) *
|
||||
scale,
|
||||
options.scale,
|
||||
((frame->verts[vertexIndex].v[2] * frame->scale[2]) +
|
||||
frame->translate[2]) *
|
||||
scale);
|
||||
options.scale);
|
||||
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ BBox::BBox(const BBox& t_bbox) : CoreBBox(t_bbox) { setData(); }
|
||||
|
||||
BBox::BBox(const BBox& t_bbox, const M4x4& t_matrix) {
|
||||
for (u32 i = 0; i < 8; i++) {
|
||||
_vertices[i] = t_matrix * t_bbox._vertices[i];
|
||||
vertices[i] = t_matrix * t_bbox.vertices[i];
|
||||
}
|
||||
|
||||
setData();
|
||||
@@ -44,31 +44,31 @@ BBox BBox::getTransformed(const M4x4& t_matrix) {
|
||||
void BBox::setData() {
|
||||
// This might be shortened with Vec4 operator overloading, but current
|
||||
// implementation is more human readable.
|
||||
_height = _vertices[0].y - _vertices[2].y;
|
||||
_width = _vertices[0].x - _vertices[4].x;
|
||||
_depth = _vertices[0].z - _vertices[1].z;
|
||||
_height = vertices[0].y - vertices[2].y;
|
||||
_width = vertices[0].x - vertices[4].x;
|
||||
_depth = vertices[0].z - vertices[1].z;
|
||||
|
||||
_centerVector = _vertices[0];
|
||||
_centerVector = vertices[0];
|
||||
_centerVector.x += (_width / 2);
|
||||
_centerVector.y += (_height / 2);
|
||||
_centerVector.z += (_depth / 2);
|
||||
|
||||
// Z-Axis faces
|
||||
_frontFace = BBoxFace(_vertices[1], _vertices[7], _vertices[1].z);
|
||||
_backFace = BBoxFace(_vertices[0], _vertices[6], _vertices[0].z);
|
||||
_frontFace = BBoxFace(vertices[1], vertices[7], vertices[1].z);
|
||||
_backFace = BBoxFace(vertices[0], vertices[6], vertices[0].z);
|
||||
// X-Axis faces
|
||||
_leftFace = BBoxFace(_vertices[0], _vertices[3], _vertices[0].x);
|
||||
_rightFace = BBoxFace(_vertices[4], _vertices[7], _vertices[4].x);
|
||||
_leftFace = BBoxFace(vertices[0], vertices[3], vertices[0].x);
|
||||
_rightFace = BBoxFace(vertices[4], vertices[7], vertices[4].x);
|
||||
// Y-Axis faces
|
||||
_topFace = BBoxFace(_vertices[2], _vertices[7], _vertices[2].y);
|
||||
_bottomFace = BBoxFace(_vertices[0], _vertices[5], _vertices[0].y);
|
||||
_topFace = BBoxFace(vertices[2], vertices[7], vertices[2].y);
|
||||
_bottomFace = BBoxFace(vertices[0], vertices[5], vertices[0].y);
|
||||
}
|
||||
|
||||
Vec4 BBox::min() {
|
||||
Vec4 temp, _min;
|
||||
u8 isInitialized = 0;
|
||||
|
||||
const Vec4* vertices = getVertices();
|
||||
const Vec4* vertices = vertices;
|
||||
for (u8 i = 0; i < 8; i++) {
|
||||
temp.set(vertices[i].x, vertices[i].y, vertices[i].z, 1.0F);
|
||||
if (isInitialized == 0) {
|
||||
@@ -88,7 +88,7 @@ Vec4 BBox::max() {
|
||||
Vec4 temp, _max;
|
||||
u8 isInitialized = 0;
|
||||
|
||||
const Vec4* vertices = getVertices();
|
||||
const Vec4* vertices = vertices;
|
||||
for (u8 i = 0; i < 8; i++) {
|
||||
temp.set(vertices[i].x, vertices[i].y, vertices[i].z, 1.0F);
|
||||
if (isInitialized == 0) {
|
||||
@@ -108,7 +108,7 @@ void BBox::getMinMax(Vec4* res_min, Vec4* res_max) {
|
||||
Vec4 temp = Vec4();
|
||||
|
||||
u8 isInitialized = 0;
|
||||
const Vec4* vertices = getVertices();
|
||||
const Vec4* vertices = vertices;
|
||||
for (u8 i = 0; i < 8; i++) {
|
||||
temp.set(vertices[i].x, vertices[i].y, vertices[i].z, 1.0F);
|
||||
if (isInitialized == 0) {
|
||||
|
||||
@@ -16,38 +16,31 @@
|
||||
namespace Tyra {
|
||||
|
||||
DynamicMesh::DynamicMesh(const MeshBuilderData& data) : Mesh(data) {
|
||||
framesCount = data.materials[0]->frames.size();
|
||||
|
||||
if (framesCount == 1) {
|
||||
if (data.materials[0]->frames.size() == 1) {
|
||||
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);
|
||||
for (u32 i = 0; i < data.materials[0]->frames.size(); i++) {
|
||||
frames.push_back(new MeshFrame(data, i));
|
||||
}
|
||||
|
||||
initAnimation();
|
||||
}
|
||||
|
||||
DynamicMesh::DynamicMesh(const DynamicMesh& mesh) : Mesh(mesh) {
|
||||
framesCount = mesh.framesCount;
|
||||
|
||||
frames = new MeshFrame*[framesCount];
|
||||
for (u32 i = 0; i < framesCount; i++) {
|
||||
frames[i] = new MeshFrame(*mesh.frames[i]);
|
||||
for (u32 i = 0; i < mesh.frames.size(); i++) {
|
||||
frames.push_back(new MeshFrame(*mesh.frames[i]));
|
||||
}
|
||||
|
||||
initAnimation();
|
||||
}
|
||||
|
||||
DynamicMesh::~DynamicMesh() {
|
||||
for (u32 i = 0; i < framesCount; i++) {
|
||||
for (u32 i = 0; i < frames.size(); i++) {
|
||||
delete frames[i];
|
||||
}
|
||||
delete[] frames;
|
||||
}
|
||||
|
||||
void DynamicMesh::initAnimation() {
|
||||
@@ -62,14 +55,18 @@ void DynamicMesh::initAnimation() {
|
||||
animState.speed = 0.1F;
|
||||
}
|
||||
|
||||
void DynamicMesh::playAnimation(const u32& t_frame) {
|
||||
playAnimation(t_frame, t_frame);
|
||||
}
|
||||
|
||||
void DynamicMesh::playAnimation(const u32& t_startFrame,
|
||||
const u32& t_endFrame) {
|
||||
TYRA_ASSERT(framesCount > 0,
|
||||
TYRA_ASSERT(frames.size() > 0,
|
||||
"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.");
|
||||
TYRA_ASSERT(
|
||||
t_endFrame < framesCount,
|
||||
t_endFrame < frames.size(),
|
||||
"End frame value is too high. Valid range: (0, getFramesCount()-1)");
|
||||
animState.startFrame = t_startFrame;
|
||||
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,
|
||||
const u32& t_stayFrame) {
|
||||
TYRA_ASSERT(framesCount > 0,
|
||||
TYRA_ASSERT(frames.size() > 0,
|
||||
"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.");
|
||||
TYRA_ASSERT(
|
||||
t_endFrame < framesCount,
|
||||
t_endFrame < frames.size(),
|
||||
"End frame value is too high. Valid range: (0, getFramesCount()-1)");
|
||||
animState.startFrame = t_startFrame;
|
||||
animState.endFrame = t_endFrame;
|
||||
|
||||
@@ -19,41 +19,33 @@ Mesh::Mesh(const MeshBuilderData& data) {
|
||||
TYRA_ASSERT(data.materials.size() > 0,
|
||||
"Materials count must be greater than 0");
|
||||
|
||||
materialsCount = data.materials.size();
|
||||
materials = new MeshMaterial*[materialsCount];
|
||||
|
||||
for (u32 i = 0; i < materialsCount; i++) {
|
||||
materials[i] = new MeshMaterial(data, i);
|
||||
for (u32 i = 0; i < data.materials.size(); i++) {
|
||||
materials.push_back(new MeshMaterial(data, i));
|
||||
}
|
||||
|
||||
_isMother = true;
|
||||
isMother = true;
|
||||
}
|
||||
|
||||
Mesh::Mesh(const Mesh& mesh) {
|
||||
init();
|
||||
|
||||
materialsCount = mesh.materialsCount;
|
||||
materials = new MeshMaterial*[materialsCount];
|
||||
|
||||
for (u32 i = 0; i < materialsCount; i++) {
|
||||
materials[i] = new MeshMaterial(*mesh.materials[i]);
|
||||
for (u32 i = 0; i < mesh.materials.size(); i++) {
|
||||
materials.push_back(new MeshMaterial(*mesh.materials[i]));
|
||||
}
|
||||
|
||||
_isMother = false;
|
||||
isMother = false;
|
||||
}
|
||||
|
||||
M4x4 Mesh::getModelMatrix() const { return translation * rotation * scale; }
|
||||
|
||||
Mesh::~Mesh() {
|
||||
for (u32 i = 0; i < materialsCount; i++) {
|
||||
for (u32 i = 0; i < materials.size(); i++) {
|
||||
delete materials[i];
|
||||
}
|
||||
delete[] materials;
|
||||
}
|
||||
|
||||
void Mesh::init() {
|
||||
id = rand() % 1000000;
|
||||
materialsCount = 0;
|
||||
translation = M4x4::Identity;
|
||||
rotation = M4x4::Identity;
|
||||
scale = M4x4::Identity;
|
||||
|
||||
@@ -33,7 +33,7 @@ MeshFrame::MeshFrame(const MeshBuilderData& data, const u32& index) {
|
||||
for (u32 i = 0; i < data.materials.size(); i++) delete bboxes[i];
|
||||
delete[] bboxes;
|
||||
|
||||
_isMother = true;
|
||||
isMother = true;
|
||||
}
|
||||
|
||||
MeshFrame::MeshFrame(const MeshFrame& frame) {
|
||||
@@ -41,11 +41,11 @@ MeshFrame::MeshFrame(const MeshFrame& frame) {
|
||||
|
||||
bbox = frame.bbox;
|
||||
|
||||
_isMother = false;
|
||||
isMother = false;
|
||||
}
|
||||
|
||||
MeshFrame::~MeshFrame() {
|
||||
if (_isMother) {
|
||||
if (isMother) {
|
||||
delete bbox;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,70 +30,57 @@ MeshMaterial::MeshMaterial(const MeshBuilderData& data,
|
||||
id = rand() % 1000000;
|
||||
|
||||
if (data.lightMapEnabled) {
|
||||
singleColorFlag = false;
|
||||
lightmapFlag = false;
|
||||
TYRA_ASSERT(material->frames[0]->colors != nullptr,
|
||||
"Colors faces are required");
|
||||
} else {
|
||||
singleColorFlag = true;
|
||||
lightmapFlag = true;
|
||||
}
|
||||
|
||||
color.set(material->ambient);
|
||||
ambient.set(material->ambient);
|
||||
|
||||
_name = material->name;
|
||||
TYRA_ASSERT(_name.length() > 0, "MeshMaterial name cannot be empty");
|
||||
name = material->name;
|
||||
TYRA_ASSERT(name.length() > 0, "MeshMaterial name cannot be empty");
|
||||
|
||||
framesCount = material->frames.size();
|
||||
frames = new MeshMaterialFrame*[framesCount];
|
||||
u32 lastVertexCount = 0;
|
||||
|
||||
for (u32 i = 0; i < framesCount; i++) {
|
||||
frames[i] = new MeshMaterialFrame(data, i, materialIndex);
|
||||
for (u32 i = 0; i < material->frames.size(); i++) {
|
||||
frames.push_back(new MeshMaterialFrame(data, i, materialIndex));
|
||||
|
||||
if (i > 0) {
|
||||
TYRA_ASSERT(frames[i]->getVertexCount() == lastVertexCount,
|
||||
TYRA_ASSERT(frames[i]->count == lastVertexCount,
|
||||
"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) {
|
||||
id = rand() % 1000000;
|
||||
|
||||
singleColorFlag = mesh.singleColorFlag;
|
||||
framesCount = mesh.framesCount;
|
||||
_name = mesh._name;
|
||||
lightmapFlag = mesh.lightmapFlag;
|
||||
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 < framesCount; i++) {
|
||||
frames[i] = new MeshMaterialFrame(*mesh.frames[i]);
|
||||
for (u32 i = 0; i < mesh.frames.size(); i++) {
|
||||
frames.push_back(new MeshMaterialFrame(*mesh.frames[i]));
|
||||
}
|
||||
|
||||
_isMother = false;
|
||||
isMother = false;
|
||||
}
|
||||
|
||||
MeshMaterial::~MeshMaterial() {
|
||||
for (u32 i = 0; i < framesCount; i++) {
|
||||
for (u32 i = 0; i < frames.size(); i++) {
|
||||
delete frames[i];
|
||||
}
|
||||
delete[] frames;
|
||||
}
|
||||
|
||||
const BBox& MeshMaterial::getBBox(const u32& frame) const {
|
||||
return frames[frame]->getBBox();
|
||||
}
|
||||
|
||||
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;
|
||||
return *frames[frame]->bbox;
|
||||
}
|
||||
|
||||
void MeshMaterial::print() const {
|
||||
@@ -117,9 +104,9 @@ std::string MeshMaterial::getPrint(const char* name) const {
|
||||
res << std::endl;
|
||||
res << std::fixed << std::setprecision(2);
|
||||
res << "Id: " << id << ", " << std::endl;
|
||||
res << "Name: " << _name << ", " << std::endl;
|
||||
res << "Frames count: " << framesCount << ", " << std::endl;
|
||||
res << "Single color?: " << static_cast<u32>(singleColorFlag) << std::endl;
|
||||
res << "Name: " << name << ", " << std::endl;
|
||||
res << "Frames count: " << frames.size() << ", " << std::endl;
|
||||
res << "Single color?: " << static_cast<u32>(lightmapFlag) << std::endl;
|
||||
res << ")";
|
||||
|
||||
return res.str();
|
||||
|
||||
@@ -44,11 +44,32 @@ MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data,
|
||||
|
||||
count = frame->count;
|
||||
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) {
|
||||
@@ -63,11 +84,11 @@ MeshMaterialFrame::MeshMaterialFrame(const MeshMaterialFrame& frame) {
|
||||
|
||||
bbox = frame.bbox;
|
||||
|
||||
_isMother = false;
|
||||
isMother = false;
|
||||
}
|
||||
|
||||
MeshMaterialFrame::~MeshMaterialFrame() {
|
||||
if (_isMother) {
|
||||
if (isMother) {
|
||||
delete[] vertices;
|
||||
if (normals) delete[] normals;
|
||||
if (textureCoords) delete[] textureCoords;
|
||||
|
||||
@@ -62,8 +62,8 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
|
||||
PipelineDirLightsBag* dirLights = nullptr;
|
||||
|
||||
if (options->frustumCulling == PipelineFrustumCulling_Simple) {
|
||||
auto* frameTo = mesh->getFrame(mesh->getNextAnimationFrame());
|
||||
if (frameTo->getBBox().isInFrustum(
|
||||
auto* frameTo = mesh->frames[mesh->animState.nextFrame];
|
||||
if (frameTo->bbox->isInFrustum(
|
||||
rendererCore->renderer3D.frustumPlanes.getAll(), model) ==
|
||||
CoreBBoxFrustum::OUTSIDE_FRUSTUM) {
|
||||
return;
|
||||
@@ -82,17 +82,15 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
|
||||
setBuffersDefaultVars(buffers, mesh, infoBag);
|
||||
core.begin(infoBag);
|
||||
|
||||
for (u32 i = 0; i < mesh->getMaterialsCount(); i++) {
|
||||
auto* material = mesh->getMaterial(i);
|
||||
auto* frameFrom = material->getFrame(mesh->getCurrentAnimationFrame());
|
||||
auto* frameTo = material->getFrame(mesh->getNextAnimationFrame());
|
||||
for (u32 i = 0; i < mesh->materials.size(); i++) {
|
||||
auto* material = mesh->materials[i];
|
||||
auto* frameFrom = material->frames[mesh->animState.currentFrame];
|
||||
auto* frameTo = material->frames[mesh->animState.nextFrame];
|
||||
|
||||
auto partSize =
|
||||
core.getMaxVertCountByParams(options && options->lighting,
|
||||
material->getFrame(0)->getTextureCoords());
|
||||
auto partSize = core.getMaxVertCountByParams(
|
||||
options && options->lighting, material->frames[0]->textureCoords);
|
||||
|
||||
u32 partsCount =
|
||||
ceil(frameFrom->getVertexCount() / static_cast<float>(partSize));
|
||||
u32 partsCount = ceil(frameFrom->count / static_cast<float>(partSize));
|
||||
|
||||
auto* colorBag = getColorBag(material);
|
||||
|
||||
@@ -103,9 +101,8 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) {
|
||||
auto& buffer = buffers[bufferIndex];
|
||||
|
||||
freeBuffer(&buffer);
|
||||
buffer.count = k == partsCount - 1
|
||||
? frameFrom->getVertexCount() - k * partSize
|
||||
: partSize;
|
||||
buffer.count =
|
||||
k == partsCount - 1 ? frameFrom->count - k * partSize : partSize;
|
||||
|
||||
u32 startIndex = k * partSize;
|
||||
|
||||
@@ -183,7 +180,7 @@ void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers,
|
||||
DynPipInfoBag* infoBag) {
|
||||
for (u32 i = 0; i < buffersCount; i++) {
|
||||
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,
|
||||
MeshMaterialFrame* materialFrameTo,
|
||||
DynPipBag* bag, const u32& startIndex) const {
|
||||
bag->verticesFrom = &materialFrameFrom->getVertices()[startIndex];
|
||||
bag->verticesTo = &materialFrameTo->getVertices()[startIndex];
|
||||
bag->verticesFrom = &materialFrameFrom->vertices[startIndex];
|
||||
bag->verticesTo = &materialFrameTo->vertices[startIndex];
|
||||
}
|
||||
|
||||
DynPipColorBag* DynamicPipeline::getColorBag(MeshMaterial* material) const {
|
||||
auto* result = new DynPipColorBag();
|
||||
result->single = &material->color;
|
||||
result->single = &material->ambient;
|
||||
return result;
|
||||
}
|
||||
|
||||
DynPipTextureBag* DynamicPipeline::getTextureBag(
|
||||
MeshMaterial* material, MeshMaterialFrame* materialFrameFrom,
|
||||
MeshMaterialFrame* materialFrameTo, const u32& startIndex) {
|
||||
if (!materialFrameFrom->getTextureCoords()) return nullptr;
|
||||
if (!materialFrameFrom->textureCoords) return nullptr;
|
||||
|
||||
auto* result = new DynPipTextureBag();
|
||||
|
||||
result->texture =
|
||||
rendererCore->texture.repository.getBySpriteOrMesh(material->getId());
|
||||
TYRA_ASSERT(
|
||||
result->texture, "Texture for material id: ", material->getId(),
|
||||
"was not found in texture repository! Did you forget to add texture?");
|
||||
rendererCore->texture.repository.getBySpriteOrMesh(material->id);
|
||||
|
||||
result->coordinatesFrom = &materialFrameFrom->getTextureCoords()[startIndex];
|
||||
result->coordinatesTo = &materialFrameTo->getTextureCoords()[startIndex];
|
||||
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->coordinatesFrom = &materialFrameFrom->textureCoords[startIndex];
|
||||
result->coordinatesTo = &materialFrameTo->textureCoords[startIndex];
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -259,7 +258,7 @@ DynPipLightingBag* DynamicPipeline::getLightingBag(
|
||||
MeshMaterialFrame* materialFrameFrom, MeshMaterialFrame* materialFrameTo,
|
||||
M4x4* model, const DynPipOptions* options,
|
||||
PipelineDirLightsBag* dirLightsBag, const u32& startIndex) const {
|
||||
if (!materialFrameFrom->getNormals() || options == nullptr ||
|
||||
if (!materialFrameFrom->normals || options == nullptr ||
|
||||
options->lighting == nullptr)
|
||||
return nullptr;
|
||||
|
||||
@@ -268,8 +267,8 @@ DynPipLightingBag* DynamicPipeline::getLightingBag(
|
||||
result->lightMatrix = model;
|
||||
result->dirLights = dirLightsBag;
|
||||
|
||||
result->normalsFrom = &materialFrameFrom->getNormals()[startIndex];
|
||||
result->normalsTo = &materialFrameTo->getNormals()[startIndex];
|
||||
result->normalsFrom = &materialFrameFrom->normals[startIndex];
|
||||
result->normalsTo = &materialFrameTo->normals[startIndex];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) {
|
||||
"matrix!");
|
||||
|
||||
if (options->frustumCulling == PipelineFrustumCulling_Simple) {
|
||||
auto* frame = mesh->getFrame();
|
||||
if (frame->getBBox().isInFrustum(
|
||||
auto* frame = mesh->frame;
|
||||
if (frame->bbox->isInFrustum(
|
||||
rendererCore->renderer3D.frustumPlanes.getAll(), model) ==
|
||||
CoreBBoxFrustum::OUTSIDE_FRUSTUM) {
|
||||
return;
|
||||
@@ -69,9 +69,9 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) {
|
||||
|
||||
if (options && options->lighting) setLightingColorsCache(options->lighting);
|
||||
|
||||
for (u32 i = 0; i < mesh->getMaterialsCount(); i++) {
|
||||
auto* material = mesh->getMaterial(i);
|
||||
auto* materialFrame = material->getFrame(0);
|
||||
for (u32 i = 0; i < mesh->materials.size(); i++) {
|
||||
auto* material = mesh->materials[i];
|
||||
auto* materialFrame = material->frames[0];
|
||||
StaPipBag bag;
|
||||
addVertices(materialFrame, &bag);
|
||||
bag.info = infoBag;
|
||||
@@ -89,8 +89,8 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) {
|
||||
|
||||
void StaticPipeline::addVertices(MeshMaterialFrame* materialFrame,
|
||||
StaPipBag* bag) const {
|
||||
bag->count = materialFrame->getVertexCount();
|
||||
bag->vertices = materialFrame->getVertices();
|
||||
bag->count = materialFrame->count;
|
||||
bag->vertices = materialFrame->vertices;
|
||||
}
|
||||
|
||||
StaPipInfoBag* StaticPipeline::getInfoBag(StaticMesh* mesh,
|
||||
@@ -118,10 +118,10 @@ StaPipColorBag* StaticPipeline::getColorBag(
|
||||
MeshMaterial* material, MeshMaterialFrame* materialFrame) const {
|
||||
auto* result = new StaPipColorBag();
|
||||
|
||||
if (material->isSingleColorActivated()) {
|
||||
result->single = &material->color;
|
||||
if (material->lightmapFlag) {
|
||||
result->single = &material->ambient;
|
||||
} else {
|
||||
result->many = materialFrame->getColors();
|
||||
result->many = materialFrame->colors;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -129,17 +129,19 @@ StaPipColorBag* StaticPipeline::getColorBag(
|
||||
|
||||
StaPipTextureBag* StaticPipeline::getTextureBag(
|
||||
MeshMaterial* material, MeshMaterialFrame* materialFrame) {
|
||||
if (!materialFrame->getTextureCoords()) return nullptr;
|
||||
if (!materialFrame->textureCoords) return nullptr;
|
||||
|
||||
auto* result = new StaPipTextureBag();
|
||||
|
||||
result->texture =
|
||||
rendererCore->texture.repository.getBySpriteOrMesh(material->getId());
|
||||
TYRA_ASSERT(
|
||||
result->texture, "Texture for material id: ", material->getId(),
|
||||
"was not found in texture repository! Did you forget to add texture?");
|
||||
rendererCore->texture.repository.getBySpriteOrMesh(material->id);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -147,13 +149,14 @@ StaPipTextureBag* StaticPipeline::getTextureBag(
|
||||
StaPipLightingBag* StaticPipeline::getLightingBag(
|
||||
MeshMaterialFrame* materialFrame, M4x4* model,
|
||||
const StaPipOptions* options) const {
|
||||
if (!materialFrame->getNormals() || options == nullptr ||
|
||||
if (!materialFrame->normals || options == nullptr ||
|
||||
options->lighting == nullptr)
|
||||
return nullptr;
|
||||
|
||||
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->lightMatrix = model;
|
||||
@@ -161,7 +164,7 @@ StaPipLightingBag* StaticPipeline::getLightingBag(
|
||||
result->dirLights->setLightsManually(
|
||||
colorsCache, options->lighting->directionalDirections);
|
||||
|
||||
result->normals = materialFrame->getNormals();
|
||||
result->normals = materialFrame->normals;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -17,71 +17,71 @@ namespace Tyra {
|
||||
|
||||
CoreBBox::CoreBBox() {
|
||||
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) {
|
||||
float lowX = t_bboxes[0]->_vertices[0].x;
|
||||
float lowY = t_bboxes[0]->_vertices[0].y;
|
||||
float lowZ = t_bboxes[0]->_vertices[0].z;
|
||||
float lowX = t_bboxes[0]->vertices[0].x;
|
||||
float lowY = t_bboxes[0]->vertices[0].y;
|
||||
float lowZ = t_bboxes[0]->vertices[0].z;
|
||||
|
||||
float hiX = t_bboxes[0]->_vertices[7].x;
|
||||
float hiY = t_bboxes[0]->_vertices[7].y;
|
||||
float hiZ = t_bboxes[0]->_vertices[7].z;
|
||||
float hiX = t_bboxes[0]->vertices[7].x;
|
||||
float hiY = t_bboxes[0]->vertices[7].y;
|
||||
float hiZ = t_bboxes[0]->vertices[7].z;
|
||||
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
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 (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 (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 (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 (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 (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;
|
||||
}
|
||||
|
||||
_vertices[0].set(lowX, lowY, lowZ);
|
||||
_vertices[1].set(lowX, lowY, hiZ);
|
||||
_vertices[2].set(lowX, hiY, lowZ);
|
||||
_vertices[3].set(lowX, hiY, hiZ);
|
||||
vertices[0].set(lowX, lowY, lowZ);
|
||||
vertices[1].set(lowX, lowY, hiZ);
|
||||
vertices[2].set(lowX, hiY, lowZ);
|
||||
vertices[3].set(lowX, hiY, hiZ);
|
||||
|
||||
_vertices[4].set(hiX, lowY, lowZ);
|
||||
_vertices[5].set(hiX, lowY, hiZ);
|
||||
_vertices[6].set(hiX, hiY, lowZ);
|
||||
_vertices[7].set(hiX, hiY, hiZ);
|
||||
vertices[4].set(hiX, lowY, lowZ);
|
||||
vertices[5].set(hiX, lowY, hiZ);
|
||||
vertices[6].set(hiX, hiY, lowZ);
|
||||
vertices[7].set(hiX, hiY, hiZ);
|
||||
}
|
||||
|
||||
CoreBBox::CoreBBox(const std::vector<CoreBBox>& t_bboxes, const u32& startIndex,
|
||||
const u32& stopIndex) {
|
||||
float lowX = t_bboxes[startIndex]._vertices[0].x;
|
||||
float lowY = t_bboxes[startIndex]._vertices[0].y;
|
||||
float lowZ = t_bboxes[startIndex]._vertices[0].z;
|
||||
float lowX = t_bboxes[startIndex].vertices[0].x;
|
||||
float lowY = t_bboxes[startIndex].vertices[0].y;
|
||||
float lowZ = t_bboxes[startIndex].vertices[0].z;
|
||||
|
||||
float hiX = t_bboxes[startIndex]._vertices[7].x;
|
||||
float hiY = t_bboxes[startIndex]._vertices[7].y;
|
||||
float hiZ = t_bboxes[startIndex]._vertices[7].z;
|
||||
float hiX = t_bboxes[startIndex].vertices[7].x;
|
||||
float hiY = t_bboxes[startIndex].vertices[7].y;
|
||||
float hiZ = t_bboxes[startIndex].vertices[7].z;
|
||||
|
||||
for (u32 i = startIndex; i < stopIndex; i++) {
|
||||
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 (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 (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 (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 (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 (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;
|
||||
}
|
||||
|
||||
_vertices[0].set(lowX, lowY, lowZ);
|
||||
_vertices[1].set(lowX, lowY, hiZ);
|
||||
_vertices[2].set(lowX, hiY, lowZ);
|
||||
_vertices[3].set(lowX, hiY, hiZ);
|
||||
vertices[0].set(lowX, lowY, lowZ);
|
||||
vertices[1].set(lowX, lowY, hiZ);
|
||||
vertices[2].set(lowX, hiY, lowZ);
|
||||
vertices[3].set(lowX, hiY, hiZ);
|
||||
|
||||
_vertices[4].set(hiX, lowY, lowZ);
|
||||
_vertices[5].set(hiX, lowY, hiZ);
|
||||
_vertices[6].set(hiX, hiY, lowZ);
|
||||
_vertices[7].set(hiX, hiY, hiZ);
|
||||
vertices[4].set(hiX, lowY, lowZ);
|
||||
vertices[5].set(hiX, lowY, hiZ);
|
||||
vertices[6].set(hiX, hiY, lowZ);
|
||||
vertices[7].set(hiX, hiY, hiZ);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
_vertices[0].set(lowX, lowY, lowZ);
|
||||
_vertices[1].set(lowX, lowY, hiZ);
|
||||
_vertices[2].set(lowX, hiY, lowZ);
|
||||
_vertices[3].set(lowX, hiY, hiZ);
|
||||
vertices[0].set(lowX, lowY, lowZ);
|
||||
vertices[1].set(lowX, lowY, hiZ);
|
||||
vertices[2].set(lowX, hiY, lowZ);
|
||||
vertices[3].set(lowX, hiY, hiZ);
|
||||
|
||||
_vertices[4].set(hiX, lowY, lowZ);
|
||||
_vertices[5].set(hiX, lowY, hiZ);
|
||||
_vertices[6].set(hiX, hiY, lowZ);
|
||||
_vertices[7].set(hiX, hiY, hiZ);
|
||||
vertices[4].set(hiX, lowY, lowZ);
|
||||
vertices[5].set(hiX, lowY, hiZ);
|
||||
vertices[6].set(hiX, hiY, lowZ);
|
||||
vertices[7].set(hiX, hiY, hiZ);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
_vertices[0].set(lowX, lowY, lowZ);
|
||||
_vertices[1].set(lowX, lowY, hiZ);
|
||||
_vertices[2].set(lowX, hiY, lowZ);
|
||||
_vertices[3].set(lowX, hiY, hiZ);
|
||||
vertices[0].set(lowX, lowY, lowZ);
|
||||
vertices[1].set(lowX, lowY, hiZ);
|
||||
vertices[2].set(lowX, hiY, lowZ);
|
||||
vertices[3].set(lowX, hiY, hiZ);
|
||||
|
||||
_vertices[4].set(hiX, lowY, lowZ);
|
||||
_vertices[5].set(hiX, lowY, hiZ);
|
||||
_vertices[6].set(hiX, hiY, lowZ);
|
||||
_vertices[7].set(hiX, hiY, hiZ);
|
||||
vertices[4].set(hiX, lowY, lowZ);
|
||||
vertices[5].set(hiX, lowY, hiZ);
|
||||
vertices[6].set(hiX, hiY, lowZ);
|
||||
vertices[7].set(hiX, hiY, hiZ);
|
||||
}
|
||||
|
||||
CoreBBox::CoreBBox(const CoreBBox& t_bbox) {
|
||||
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) {
|
||||
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 {
|
||||
@@ -167,8 +167,8 @@ std::string CoreBBox::getPrint(const char* name) const {
|
||||
res << std::fixed << std::setprecision(4);
|
||||
res << std::endl;
|
||||
for (auto i = 0; i < 8; i++) {
|
||||
res << i << ": " << _vertices[i].x << ", " << _vertices[i].y << ", "
|
||||
<< _vertices[i].z << ", " << _vertices[i].w;
|
||||
res << i << ": " << vertices[i].x << ", " << vertices[i].y << ", "
|
||||
<< vertices[i].z << ", " << vertices[i].w;
|
||||
|
||||
if (i != 7)
|
||||
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
|
||||
// both inside and out of the frustum
|
||||
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;
|
||||
|
||||
|
||||
@@ -84,15 +84,15 @@ void TextureRepository::addByMesh(Mesh* mesh, const char* directory,
|
||||
std::string dirFixed = directory;
|
||||
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 =
|
||||
dirFixed + mesh->getMaterial(i)->getName() + "." + extension;
|
||||
dirFixed + mesh->materials[i]->name + "." + extension;
|
||||
|
||||
auto* data = loader.load(fullPath.c_str());
|
||||
Texture* texture = new Texture(data);
|
||||
delete data;
|
||||
|
||||
texture->addLink(mesh->getMaterial(i)->getId());
|
||||
texture->addLink(mesh->materials[i]->id);
|
||||
textures.push_back(texture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ void Tutorial01 ::init() {
|
||||
|
||||
warrior = getWarrior(&engine->renderer);
|
||||
warriorTex = engine->renderer.core.texture.repository.getBySpriteOrMesh(
|
||||
warrior->getMaterial(0)->getId());
|
||||
warrior->materials[0]->id);
|
||||
|
||||
warriorsCount = 22;
|
||||
warriors = new DynamicMesh*[warriorsCount];
|
||||
@@ -65,10 +65,10 @@ void Tutorial01 ::init() {
|
||||
warriors[i]->translation.translateY(30.0F);
|
||||
warriors[i]->translation.translateZ(-10.0F);
|
||||
warriors[i]->translation.rotateX(-1.5F);
|
||||
warriorTex->addLink(warriors[i]->getMaterial(0)->getId());
|
||||
warriors[i]->playAnimation(0, warriors[i]->getFramesCount() - 1);
|
||||
warriors[i]->setCurrentAnimationFrame(
|
||||
getRandomInt(0, warriors[i]->getFramesCount() - 1));
|
||||
warriorTex->addLink(warriors[i]->materials[0]->id);
|
||||
warriors[i]->playAnimation(0, warriors[i]->frames.size() - 1);
|
||||
warriors[i]->animState.currentFrame =
|
||||
getRandomInt(0, warriors[i]->frames.size() - 1);
|
||||
warriors[i]->setAnimSpeed(getRandomFloat(0.1F, 0.9F));
|
||||
}
|
||||
|
||||
@@ -194,7 +194,10 @@ void Tutorial01 ::loop() {
|
||||
|
||||
StaticMesh* getStaticMesh(Renderer* renderer) {
|
||||
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);
|
||||
// result->translation.translateZ(-30.0F);
|
||||
delete data;
|
||||
@@ -223,7 +226,9 @@ StaticMesh* getSkybox(Renderer* renderer) {
|
||||
|
||||
DynamicMesh* getWarrior(Renderer* renderer) {
|
||||
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);
|
||||
// result->translation.translateZ(-30.0F);
|
||||
delete data;
|
||||
@@ -231,7 +236,7 @@ DynamicMesh* getWarrior(Renderer* renderer) {
|
||||
renderer->core.texture.repository.addByMesh(result, FileUtils::getCwd(),
|
||||
"png");
|
||||
|
||||
result->playAnimation(0, result->getFramesCount() - 1);
|
||||
result->playAnimation(0, result->frames.size() - 1);
|
||||
result->setAnimSpeed(0.15F);
|
||||
|
||||
return result;
|
||||
@@ -248,7 +253,7 @@ DynamicMesh* getCube(Renderer* renderer) {
|
||||
result->translation.translateZ(-30.0F);
|
||||
delete data;
|
||||
|
||||
result->playAnimation(0, result->getFramesCount() - 1);
|
||||
result->playAnimation(0, result->frames.size() - 1);
|
||||
result->setAnimSpeed(0.15F);
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user