Merge pull request #78 from devZoGok/develop

Develop
This commit is contained in:
devZoGok
2024-10-19 13:48:21 +00:00
committed by GitHub
35 changed files with 3266 additions and 1317 deletions
+2 -2
View File
@@ -18,8 +18,8 @@ set(MATH quaternion.cpp vector.cpp matrix.cpp rayCaster.cpp)
set(RENDER lineRenderer.cpp particleEmitter.cpp camera.cpp light.cpp material.cpp mesh.cpp meshData.cpp model.cpp node.cpp quad.cpp box.cpp root.cpp shader.cpp texture.cpp)
set(ANIM animationController.cpp animationChannel.cpp animation.cpp animatable.cpp keyframeChannel.cpp driver.cpp)
set(ARMATURE skeleton.cpp bone.cpp ikSolver.cpp)
set(ASSET_MANAGER assetManager.cpp textAsset.h imageAsset.h modelAsset.h fontAsset.h)
set(ASSET_READERS imageReader.cpp fontReader.cpp modelReader.cpp xmlModelReader.cpp)
set(ASSET_MANAGER assetManager.cpp shaderAsset.h textAsset.h imageAsset.h modelAsset.h fontAsset.h)
set(ASSET_READERS shaderReader.cpp imageReader.cpp fontReader.cpp modelReader.cpp xmlModelReader.cpp)
if(BUILD_WITH_ASSIMP)
set(ASSET_READERS ${ASSET_READERS} assimpModelReader.cpp)
+8
View File
@@ -154,6 +154,14 @@ namespace vb01Gui{
textboxes.push_back(t);
}
Button* AbstractGuiManager::getButton(string name){
for(Button *b : buttons)
if(b->getName() == name)
return b;
return nullptr;
}
void AbstractGuiManager::removeButton(Button *b) {
for (int i = 0; i < buttons.size(); i++) {
if (b == buttons[i]) {
+1
View File
@@ -22,6 +22,7 @@ namespace vb01Gui{
std::vector<Button*> findClickedButtons();
void updateGui();
void addButton(Button *b){buttons.push_back(b);}
Button* getButton(std::string);
void removeButton(Button*);
void removeButton(std::string);
void addListbox(Listbox*);
+34
View File
@@ -1,8 +1,13 @@
#include "assetManager.h"
#include "abstractAssetReader.h"
#include "util.h"
#include "root.h"
#include "node.h"
#include "mesh.h"
#include "material.h"
#include "imageReader.h"
#include "fontReader.h"
#include "shaderReader.h"
#include "xmlModelReader.h"
#include <tinydir.h>
@@ -71,6 +76,11 @@ namespace vb01{
if(find(modelFormats.begin(), modelFormats.end(), format) != modelFormats.end())
assetReader = XmlModelReader::getSingleton();
vector<string> shaderFormats = vector<string>{"vert", "frag", "geo"};
if(find(shaderFormats.begin(), shaderFormats.end(), format) != shaderFormats.end())
assetReader = ShaderReader::getSingleton();
if(assetReader)
assets.push_back(assetReader->readAsset(file));
else
@@ -85,4 +95,28 @@ namespace vb01{
return nullptr;
}
void AssetManager::editAsset(string path, Asset &newAsset){
ShaderAsset *oldAsset = (ShaderAsset*)getAsset(path);
if(oldAsset){
oldAsset->shaderString = ((ShaderAsset&)newAsset).shaderString;
Root *root = Root::getSingleton();
vector<Node*> descendants;
root->getRootNode()->getDescendants(descendants);
root->getGuiNode()->getDescendants(descendants);
for(Node *desc : descendants){
vector<Mesh*> meshes = desc->getMeshes();
for(Mesh *mesh : meshes){
Material *mat = mesh->getMaterial();
if(mat)
mat->getShader()->loadShaders();
}
}
}
}
}
+1
View File
@@ -12,6 +12,7 @@ namespace vb01{
public:
static AssetManager* getSingleton();
void load(std::string, bool = false);
void editAsset(std::string, Asset&);
Asset* getAsset(std::string);
inline Asset* getAsset(int i){return assets[i];}
inline std::vector<Asset*> getAssets(){return assets;}
+20 -24
View File
@@ -9,27 +9,23 @@ namespace vb01{
void Box::setSize(Vector3 size){
this->size = size;
Vector3 pos[] = {
Vector3(size.x / 2, size.y / 2, size.z / 2),
Vector3(-size.x / 2, size.y / 2, size.z / 2),
Vector3(-size.x / 2, size.y / 2, -size.z / 2),
Vector3(size.x / 2, size.y / 2, -size.z / 2),
Vector3 *pos = new Vector3[8];
pos[0] = Vector3(size.x / 2, size.y / 2, size.z / 2);
pos[1] = Vector3(-size.x / 2, size.y / 2, size.z / 2);
pos[2] = Vector3(-size.x / 2, size.y / 2, -size.z / 2);
pos[3] = Vector3(size.x / 2, size.y / 2, -size.z / 2);
pos[4] = Vector3(size.x / 2, -size.y / 2, size.z / 2);
pos[5] = Vector3(-size.x / 2, -size.y / 2, size.z / 2);
pos[6] = Vector3(-size.x / 2, -size.y / 2, -size.z / 2);
pos[7] = Vector3(size.x / 2, -size.y / 2, -size.z / 2);
Vector3(size.x / 2, -size.y / 2, size.z / 2),
Vector3(-size.x / 2, -size.y / 2, size.z / 2),
Vector3(-size.x / 2, -size.y / 2, -size.z / 2),
Vector3(size.x / 2, -size.y / 2, -size.z / 2)
};
Vector3 norm[] = {
Vector3(0, 0, 1),
Vector3(0, 1, 0),
Vector3(1, 0, 0),
Vector3(0, 0, -1),
Vector3(0, -1, 0),
Vector3(-1, 0, 0)
};
Vector3 *norm = new Vector3[6];
norm[0] = Vector3(0, 0, 1);
norm[1] = Vector3(0, 1, 0);
norm[2] = Vector3(1, 0, 0);
norm[3] = Vector3(0, 0, -1);
norm[4] = Vector3(0, -1, 0);
norm[5] = Vector3(-1, 0, 0);
Vector2 tex[] = {
Vector2(1, 1),
@@ -63,14 +59,14 @@ namespace vb01{
MeshData::Vertex *vertices = new MeshData::Vertex[3 * numTris];
for(int i = 0; i < 3 * numTris; i++){
MeshData::Vertex v;
v.pos = pos[data[3 * i]];
v.norm = norm[data[3 * i + 1]];
MeshData::Vertex v;
v.pos = &pos[data[3 * i]];
v.norm = &norm[data[3 * i + 1]];
v.uv = tex[data[3 * i + 2]];
vertices[i] = v;
indices[i] = i;
}
meshBase = MeshData(vertices, indices, numTris);
meshBase = MeshData(pos, nullptr, nullptr, nullptr, 8, norm, vertices, indices, numTris);
}
}
+1 -1
View File
@@ -46,7 +46,7 @@ namespace vb01Gui{
rectNode->attachMesh(rect);
guiNode->attachChild(rectNode);
if(separate){
if(separate && fontPath != ""){
text = new Text(fontPath, stringToWstring(name));
float sc = .2;
+5 -4
View File
@@ -24,18 +24,19 @@ namespace vb01Gui{
virtual void onMouseOver();
virtual void onMouseOff();
virtual void onClick(){}
inline vb01::Vector3 getPos(){return pos;}
void setPos(vb01::Vector3);
inline vb01::Vector2 getSize(){return size;}
void setSize(vb01::Vector2);
void setColor(vb01::Vector4);
void setImage(std::string);
inline vb01::Node* getRectNode(){return rectNode;}
inline vb01::Vector3 getPos(){return pos;}
inline vb01::Vector2 getSize(){return size;}
inline std::string getName(){return name;}
inline void setActive(bool active){this->active = active;}
inline bool isSeparate(){return separate;}
inline bool isActive(){return active;}
inline vb01::Vector4 getColor(){return color;}
inline int getTrigger(){return trigger;}
void setColor(vb01::Vector4);
void setImage(std::string);
protected:
int trigger, initWindowSize[2];
bool separate, active = true, mouseOver = false;
+1724
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -5,15 +5,16 @@
namespace vb01{
struct ImageAsset : public Asset{
ImageAsset(std::string path, u8 *image, int width, int height){
ImageAsset(std::string path, u8 *image, int width, int height, int numChannels){
this->path = path;
this->image = image;
this->width = width;
this->height = height;
this->numChannels = numChannels;
}
u8 *image;
int width, height;
int width, height, numChannels;
};
}
+1 -1
View File
@@ -18,6 +18,6 @@ namespace vb01{
stbi_set_flip_vertically_on_load(flip);
int width, height, numChannels;
u8 *data = stbi_load(path.c_str(), &width, &height, &numChannels, 0);
return new ImageAsset(path, data, width, height);
return new ImageAsset(path, data, width, height, numChannels);
}
}
+17 -4
View File
@@ -75,32 +75,39 @@ namespace vb01{
glBindFramebuffer(GL_FRAMEBUFFER, *(Root::getSingleton()->getFBO()));
}
void Light::update(){
void Light::update(bool render){
Root *root = Root::getSingleton();
Node *rootNode = root->getRootNode();
vector<Node*> descendants;
rootNode->getDescendants(descendants);
descendants.push_back(rootNode);
vector<Light*> lights;
vector<Material*> materials;
for(Node *d : descendants){
for(Light *l : d->getLights())
lights.push_back(l);
for(Mesh *m : d->getMeshes())
materials.push_back(m->getMaterial());
for(Mesh *mesh : d->getMeshes())
materials.push_back(mesh->getMaterial());
}
int thisId = -1;
for(int i = 0; i < lights.size(); i++)
if(lights[i] == this)
thisId = i;
for(Material *mat : materials){
Shader *shader = mat->getShader();
shader->use();
shader->setBool(render, "lights[" + to_string(thisId) + "].render");
}
mat4 proj = mat4(1.), view = mat4(1.);
renderShadow(descendants, proj, view);
updateShader(materials, thisId, proj, view);
}
void Light::renderShadow(std::vector<Node*> descendants, mat4 &proj, mat4 &view){
@@ -176,8 +183,10 @@ namespace vb01{
glViewport(0, 0, root->getWidth(), root->getHeight());
}
//TODO replace depth map id literals
void Light::updateShader(vector<Material*> materials, int thisId, mat4 &proj, mat4 &view){
Vector3 position = node->localToGlobalPosition(Vector3::VEC_ZERO), direction = node->getGlobalAxis(2);
for(Material *m : materials){
Shader *shader = m->getShader();
shader->use();
@@ -185,6 +194,7 @@ namespace vb01{
shader->setVec3(color, "lights[" + to_string(thisId) + "].color");
shader->setFloat(nearPlane, "lights[" + to_string(thisId) + "].near");
shader->setFloat(farPlane, "lights[" + to_string(thisId) + "].far");
shader->setBool(additiveLighting, "lights[" + to_string(thisId) + "].additive");
int depthMapId = 10;
shader->setInt(depthMapId, "lights[" + to_string(thisId) + "].depthMap");
@@ -194,9 +204,12 @@ namespace vb01{
switch(type){
case POINT:
shader->setVec3(position, "lights[" + to_string(thisId) + "].pos");
shader->setInt((int)attenuation, "lights[" + to_string(thisId) + "].attenuation");
shader->setFloat(radius, "lights[" + to_string(thisId) + "].radius");
shader->setFloat(attenuationValues.x, "lights[" + to_string(thisId) + "].a");
shader->setFloat(attenuationValues.y, "lights[" + to_string(thisId) + "].b");
shader->setFloat(attenuationValues.z, "lights[" + to_string(thisId) + "].c");
shader->setBool(useAngle, "lights[" + to_string(thisId) + "].useAngle");
break;
case DIRECTIONAL:
shader->setMat4(proj * view, "lights[" + to_string(thisId) + "].lightMat");
+14 -2
View File
@@ -17,10 +17,13 @@ namespace vb01{
class Light : public Animatable, public Attachable{
public:
enum Type{POINT, DIRECTIONAL, SPOT, AMBIENT};
enum Attenuation{QUADRATIC, LINEAR, NONE};
Light(Type, std::string = "");
~Light();
void update();
void update(bool);
inline Vector3 getColor(){return color;}
inline Type getLightType(){return type;}
inline void setColor(Vector3 color){this->color = color;}
inline void setAttenuationValues(float a, float b, float c){
attenuationValues.x = a;
@@ -31,7 +34,14 @@ namespace vb01{
inline void setOuterAngle(float outerAngle){this->outerAngle = outerAngle;}
inline void setShadowNearPlane(float nearPlane){this->nearPlane = nearPlane;}
inline void setShadowFarPlane(float farPlane){this->farPlane = farPlane;}
inline void setAttenuation(Attenuation at){this->attenuation = at;}
inline void setRadius(float r){this->radius = r;}
inline void setAdditiveLighting(bool al){this->additiveLighting = al;}
inline void setUseAngle(bool ua){this->useAngle = ua;}
inline Attenuation getAttenuation(){return attenuation;}
inline Vector3 getAttenuationValues(){return attenuationValues;}
inline bool isAdditiveLighting(){return additiveLighting;}
inline float getRadius(){return radius;}
inline float getInnerAngle(){return innerAngle;}
inline float getOuterAngle(){return outerAngle;}
inline float getShadowNearPlane(){return nearPlane;}
@@ -43,10 +53,12 @@ namespace vb01{
void updateShader(std::vector<Material*>, int, glm::mat4&, glm::mat4&);
Type type;
bool additiveLighting = true, useAngle = true;
Attenuation attenuation = Attenuation::QUADRATIC;
Shader *depthMapShader;
Texture *depthMap = nullptr;
Vector3 color = Vector3::VEC_IJK, attenuationValues = Vector3(1.8, .7, 1);
float innerAngle = .707, outerAngle = .714, nearPlane = .1, farPlane = 100;
float innerAngle = .707, outerAngle = .714, nearPlane = .1, farPlane = 100, radius = 0;
unsigned int depthmapFBO, depthMapSize = 1024;
};
}
+17 -10
View File
@@ -44,31 +44,35 @@ namespace vb01{
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
u32 size = sizeof(MeshData::Vertex);
u32 size = sizeof(MeshData::GpuVertex);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 3 * meshBase.numTris * size, meshBase.vertices, GL_DYNAMIC_DRAW);
MeshData::GpuVertex *glVertData = meshBase.toGpuVerts();
glBufferData(GL_ARRAY_BUFFER, 3 * meshBase.numTris * size, glVertData, GL_DYNAMIC_DRAW);
delete glVertData;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * meshBase.numTris * sizeof(u32), meshBase.indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, size, (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, norm)));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, norm)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, uv)));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, uv)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, tan)));
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, tan)));
glEnableVertexAttribArray(3);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, biTan)));
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, biTan)));
glEnableVertexAttribArray(4);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, weights)));
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, weights)));
glEnableVertexAttribArray(5);
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, boneIndices)));
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, boneIndices)));
glEnableVertexAttribArray(6);
for(int i = 0; i < meshBase.numShapeKeys; i++){
glVertexAttribPointer(7 + i, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::Vertex, shapeKeyOffsets) + 3 * i * sizeof(float)));
glVertexAttribPointer(7 + i, 3, GL_FLOAT, GL_FALSE, size, (void*)(offsetof(MeshData::GpuVertex, shapeKeyOffsets) + 3 * i * sizeof(float)));
glEnableVertexAttribArray(7 + i);
}
}
@@ -91,7 +95,10 @@ namespace vb01{
void Mesh::updateVerts(MeshData meshData){
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * sizeof(MeshData::Vertex) * meshBase.numTris, meshData.vertices);
MeshData::GpuVertex *glVertData = meshBase.toGpuVerts();
glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * sizeof(MeshData::GpuVertex) * meshBase.numTris, glVertData);
delete glVertData;
}
void Mesh::update(){
+23 -16
View File
@@ -17,22 +17,29 @@ namespace vb01{
}
}
MeshData::ShapeKey::ShapeKey(string name, float value, float minValue, float maxValue) : Animatable(Animatable::SHAPE_KEY, name){
this->name = name;
this->value = value;
this->minValue = minValue;
this->maxValue = maxValue;
}
MeshData::GpuVertex* MeshData::toGpuVerts(){
int numVertices = 3 * numTris;
GpuVertex *vertData = new GpuVertex[numVertices];
MeshData::MeshData(Vertex *vertices, u32 *indices, int numTris, string attachableName, string *vertexGroups, int numVertexGroups, string fullSkeletonName, ShapeKey *shapeKeys, int numShapeKeys){
this->vertices = vertices;
this->indices = indices;
this->numTris = numTris;
this->attachableName = attachableName;
this->vertexGroups = vertexGroups;
this->numVertexGroups = numVertexGroups;
this->fullSkeletonName = fullSkeletonName;
this->shapeKeys = shapeKeys;
this->numShapeKeys = numShapeKeys;
for(int i = 0; i < numVertices; i++){
vertData[i].pos = *vertices[i].pos;
vertData[i].norm = *vertices[i].norm;
vertData[i].tan = vertices[i].tan;
vertData[i].biTan = vertices[i].biTan;
vertData[i].uv = vertices[i].uv;
if(weights){
for(int j = 0; j < 4; j++){
vertData[i].weights[j] = vertices[i].weights[j];
vertData[i].boneIndices[j] = vertices[i].boneIndices[j];
}
}
if(shapeKeyOffsets)
for(int j = 0; j < 100; j++)
vertData[i].shapeKeyOffsets[j] = vertices[i].shapeKeyOffsets[j];
}
return vertData;
}
}
+32 -4
View File
@@ -14,12 +14,12 @@ namespace vb01{
std::string name;
float minValue, value, maxValue;
ShapeKey(std::string, float, float, float);
ShapeKey(std::string n, float v, float mnv, float mxv) : name(n), value(v), minValue(mnv), maxValue(mxv), Animatable(Animatable::SHAPE_KEY, n){}
ShapeKey() : Animatable(Animatable::SHAPE_KEY){}
void animate(float, KeyframeChannel);
};
struct Vertex{
struct GpuVertex{
Vector3 pos, norm, tan, biTan;
Vector2 uv;
float weights[4]{0, 0, 0, 0};
@@ -27,15 +27,43 @@ namespace vb01{
Vector3 shapeKeyOffsets[100];
};
struct Vertex{
Vector3 *pos = nullptr, *norm = nullptr, tan, biTan;
Vector2 uv;
float *weights = nullptr;
int *boneIndices = nullptr;
Vector3 *shapeKeyOffsets = nullptr;
};
GpuVertex* toGpuVerts();
Vector3 *positions = nullptr, *normals = nullptr, **shapeKeyOffsets = nullptr;
float **weights = nullptr;
int **boneIndices = nullptr;
Vertex *vertices;
std::string *vertexGroups = nullptr;
ShapeKey *shapeKeys = nullptr;
u32 *indices, VAO, VBO, EBO;
int numTris, numVertexGroups = 0, numShapeKeys = 0;
int numPos, numTris, numVertexGroups = 0, numShapeKeys = 0;
std::string attachableName = "", fullSkeletonName = "";
MeshData(){}
MeshData(Vertex*, u32*, int, std::string = "", std::string *vg = nullptr, int = 0, std::string = "", ShapeKey *sk = nullptr, int = 0);
MeshData(Vector3 *pos, float **w, int **bi, Vector3 **sko, int np, Vector3 *norm, Vertex *vert, u32 *ind, int nt, std::string an = "", std::string *vg = nullptr, int nvg = 0, std::string fsn = "", ShapeKey *sk = nullptr, int nsk = 0) :
positions(pos),
weights(w),
boneIndices(bi),
shapeKeyOffsets(sko),
numPos(np),
normals(norm),
vertices(vert),
indices(ind),
numTris(nt),
vertexGroups(vg),
numVertexGroups(nvg),
fullSkeletonName(fsn),
shapeKeys(sk),
numShapeKeys(nsk)
{}
};
}
-2
View File
@@ -28,8 +28,6 @@ namespace vb01{
}
Model::~Model(){
delete children[0]->getMesh(0)->getMaterial();
vector<Node*> descendants;
getDescendants(descendants);
+36 -24
View File
@@ -1,12 +1,15 @@
#include "root.h"
#include "bone.h"
#include "mesh.h"
#include "particleEmitter.h"
#include "light.h"
#include "text.h"
#include "material.h"
#include "util.h"
#include "light.h"
#include "matrix.h"
#include "material.h"
#include "skeleton.h"
#include "shaderAsset.h"
#include "particleEmitter.h"
#include "assetManager.h"
#include "animationController.h"
#include <glm.hpp>
@@ -53,10 +56,10 @@ namespace vb01{
if(!render) break;
}
if(render){
for(Light *l : lights)
l->update();
for(Light *l : lights)
l->update(render);
if(render){
for(Mesh *m : meshes)
m->update();
@@ -245,6 +248,19 @@ namespace vb01{
lights.push_back(light);
light->onAttached(this);
updateShaders();
}
void Node::removeLight(Light *light){
for(int i = 0; i < lights.size(); i++)
if(lights[i] == light){
lights.erase(lights.begin() + i);
Root::getSingleton()->shiftNumLights(false);
updateShaders();
break;
}
}
void Node::removeLight(int id){
@@ -439,27 +455,23 @@ namespace vb01{
void Node::updateShaders(){
Root *root = Root::getSingleton();
AssetManager *am = AssetManager::getSingleton();
ShaderAsset *sa = (ShaderAsset*)am->getAsset(root->getLibPath() + "texture.frag");
string shaderStr = sa->shaderString;
int numLights = root->getNumLights();
Node *rootNode = root->getRootNode();
vector<Node*> descendants;
rootNode->getDescendants(descendants);
descendants.push_back(rootNode);
string str1 = "const int numLights = " + to_string(numLights > 0 ? numLights : 1) + ";";
int a1 = findNthOccurence(shaderStr, "\n", 0);
int a2 = findNthOccurence(shaderStr, "\n", 1);
shaderStr.replace(a1 + 1, a2 - a1 - 1, str1);
for(Node *n : descendants){
vector<Mesh*> meshes = n->getMeshes();
string str2 = "const bool checkLights = " + string(numLights > 0 ? "true" : "false") + ";";
a1 = findNthOccurence(shaderStr, "\n", 1);
a2 = findNthOccurence(shaderStr, "\n", 2);
shaderStr.replace(a1 + 1, a2 - a1 - 1, str2);
for(Mesh *m : meshes){
Material *mat = m->getMaterial();
if(mat){
int numLights = root->getNumLights();
string str1 = "const int numLights = " + to_string(numLights > 0 ? numLights : 1) + ";";
mat->getShader()->editShader(Shader::FRAGMENT_SHADER, 1, str1);
string str2 = "const bool checkLights = " + string(numLights > 0 ? "true" : "false") + ";";
mat->getShader()->editShader(Shader::FRAGMENT_SHADER, 2, str2);
}
}
}
ShaderAsset sa2(sa->path, shaderStr);
am->editAsset(sa->path, sa2);
}
void Node::setOrientation(Quaternion q){
+1
View File
@@ -31,6 +31,7 @@ namespace vb01{
void attachChild(Node*);
void dettachChild(Node*);
void addLight(Light*);
void removeLight(Light*);
void removeLight(int);
void addText(Text*);
virtual void lookAt(Vector3, Vector3);
+52 -31
View File
@@ -1,6 +1,10 @@
#include "quad.h"
#include <algorithm>
namespace vb01{
using namespace std;
Quad::Quad(Vector3 size, bool spatial, int numVertDiv, int numHorDiv){
this->spatial = spatial;
this->numVertDiv = numVertDiv;
@@ -14,55 +18,72 @@ namespace vb01{
this->size = size;
const int numHorQuads = numVertDiv + 1, numVertQuads = numHorDiv + 1;
const int numTris = 2 * numHorQuads * numVertQuads, numVerts = 3 * numTris;
const int numVertPos = (numHorQuads + 1) * (numVertQuads + 1), numTris = 2 * numHorQuads * numVertQuads, numVerts = 3 * numTris;
Vector2 subQuadSize = Vector2(size.x / numHorQuads, size.y / numVertQuads);
MeshData::Vertex *vertices = new MeshData::Vertex[numVerts];
if(!meshBase.positions){
meshBase.positions = new Vector3[numVertPos];
meshBase.normals = new Vector3(Vector3::VEC_J);
meshBase.indices = new u32[numVerts];
for(int i = 0; i < numVerts; i++)
meshBase.indices[i] = i;
}
Vector3 *faceVertPos = meshBase.positions;
Vector3 *norm = meshBase.normals;
u32 *indices = meshBase.indices;
for(int i = 0; i < numHorQuads; i++){
for(int j = 0; j < numVertQuads; j++){
int id = i * 6 * numHorQuads + j * 6;
int vertPosId = i * (numHorQuads + 1) + j;
int vertPosId2 = (i + 1) * (numHorQuads + 1) + j;
Vector2 offset = Vector2(subQuadSize.x, subQuadSize.y);
Vector3 faceVertPos[]{
Vector3(-.5 * size.x + offset.x * j, 0, -.5 * size.y + offset.y * i),
Vector3(-.5 * size.x + offset.x * (j + 1), 0, -.5 * size.y + offset.y * (i + 1)),
Vector3(-.5 * size.x + offset.x * (j + 1), 0, -.5 * size.y + offset.y * i),
Vector3(-.5 * size.x + offset.x * j, 0, -.5 * size.y + offset.y * i),
Vector3(-.5 * size.x + offset.x * j, 0, -.5 * size.y + offset.y * (i + 1)),
Vector3(-.5 * size.x + offset.x * (j + 1), 0, -.5 * size.y + offset.y * (i + 1))
};
faceVertPos[vertPosId] = Vector3(-.5 * size.x + offset.x * i, 0, -.5 * size.y + offset.y * j);
faceVertPos[vertPosId + 1] = Vector3(-.5 * size.x + offset.x * i, 0, -.5 * size.y + offset.y * (j + 1));
faceVertPos[vertPosId2] = Vector3(-.5 * size.x + offset.x * (i + 1), 0, -.5 * size.y + offset.y * j);
faceVertPos[vertPosId2 + 1] = Vector3(-.5 * size.x + offset.x * (i + 1), 0, -.5 * size.y + offset.y * (j + 1));
if(!spatial){
int ids[4]{vertPosId, vertPosId + 1, vertPosId2, vertPosId2 + 1};
swap(faceVertPos[ids[0]].z, faceVertPos[ids[1]].z);
swap(faceVertPos[ids[2]].z, faceVertPos[ids[3]].z);
for(int k = 0; k < 4; k++){
faceVertPos[ids[k]].y = -faceVertPos[ids[k]].z;
faceVertPos[ids[k]].z = 0;
faceVertPos[ids[k]] += .5 * Vector3(size.x, size.y, 0);
}
}
Vector2 faceVertUv[]{
Vector2(float(j) / numHorQuads, float(i) / numVertQuads),
Vector2(float(j + 1) / numHorQuads, float(i + 1) / numVertQuads),
Vector2(float(j + 1) / numHorQuads, float(i) / numVertQuads),
Vector2(float(j) / numHorQuads, float(i) / numVertQuads),
Vector2(float(j) / numHorQuads, float(i + 1) / numVertQuads),
Vector2(float(j + 1) / numHorQuads, float(i + 1) / numVertQuads),
Vector2(float(i) / numHorQuads, 1 - float(j) / numVertQuads),
Vector2(float(i) / numHorQuads, 1 - float(j + 1) / numVertQuads),
Vector2(float(i + 1) / numHorQuads, 1 - float(j + 1) / numVertQuads),
Vector2(float(i + 1) / numHorQuads, 1 - float(j + 1) / numVertQuads),
Vector2(float(i + 1) / numHorQuads, 1 - float(j) / numVertQuads),
Vector2(float(i) / numHorQuads, 1 - float(j) / numVertQuads),
};
int quadId = 6 * (i * numHorQuads + j);
int vertPosIds[6]{vertPosId, vertPosId + 1, vertPosId2 + 1, vertPosId2 + 1, vertPosId2, vertPosId};
for(int k = 0; k < 6; k++){
if(!spatial){
faceVertPos[k].y = -faceVertPos[k].z;
faceVertPos[k].z = 0;
faceVertPos[k] += .5 * Vector3(size.x, size.y, 0);
}
MeshData::Vertex v;
v.pos = faceVertPos[k];
v.pos = &faceVertPos[vertPosIds[k]];
v.uv = faceVertUv[k];
v.tan = Vector3::VEC_I;
v.norm = Vector3::VEC_J;
v.norm = norm;
v.biTan = Vector3::VEC_K;
vertices[id + k] = v;
vertices[quadId + k] = v;
}
}
}
u32 *indices = new u32[numVerts];
for(int i = 0; i < numVerts; i++)
indices[i] = i;
meshBase = MeshData(vertices, indices, numTris);
meshBase = MeshData(faceVertPos, nullptr, nullptr, nullptr, 6, norm, vertices, indices, numTris);
}
}
+2 -2
View File
@@ -42,7 +42,7 @@ namespace vb01{
bool skip = false;
for(int j = 0; j < 3; j++){
Vector3 rayPosToVert = (vertices[i * 3 + j].pos - rayPos);
Vector3 rayPosToVert = (*(vertices[i * 3 + j].pos) - rayPos);
float angle = rayDir.getAngleBetween(rayPosToVert.norm());
if(angle > PI / 2) angle = PI - angle;
@@ -58,7 +58,7 @@ namespace vb01{
if(skip) continue;
}
Vector3 pointA = pos + rot * vertices[indices[i * 3]].pos, pointB = pos + rot * vertices[indices[i * 3 + 1]].pos, pointC = pos + rot * vertices[indices[i * 3 + 2]].pos;
Vector3 pointA = pos + rot * *(vertices[indices[i * 3]].pos), pointB = pos + rot * *(vertices[indices[i * 3 + 1]].pos), pointC = pos + rot * *(vertices[indices[i * 3 + 2]].pos);
Vector3 hypVec = pointA - rayPos;
Vector3 perpVec = (pointB - pointA).cross(pointC - pointA).norm();
float a1 = hypVec.norm().getAngleBetween(perpVec);
+5 -1
View File
@@ -5,6 +5,7 @@
#include "box.h"
#include "quad.h"
#include "lineRenderer.h"
#include "assetManager.h"
#include "animationController.h"
#include "glad.h"
@@ -22,6 +23,7 @@ namespace vb01{
Root* Root::getSingleton(){
if(!root)
root = new Root();
return root;
}
@@ -47,6 +49,8 @@ namespace vb01{
this->height = height;
this->libPath = libPath;
AssetManager::getSingleton()->load(Root::getSingleton()->getLibPath());
initWindow(name);
brdfLutPlane = new Quad(Vector3(1, 1, 1) * 2);
@@ -59,7 +63,7 @@ namespace vb01{
initBloomFramebuffer();
initGuiPlane(fragTexture, brightTexture);
shader = new Shader(Root::getSingleton()->getLibPath() + "line3D");
shader = new Shader(Root::getSingleton()->getLibPath() + "line3D");
}
void Root::initWindow(string name){
+1034 -1034
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -166,6 +166,7 @@ def export(node, parentTag):
if node.type == 'MESH':
mesh = node.data
numVertexPos = len(mesh.vertices)
numFaces = len(mesh.polygons)
numVerts = len(mesh.vertices)
numGroups = len(node.vertex_groups)
@@ -176,6 +177,7 @@ def export(node, parentTag):
meshTag = ET.SubElement(nodeTag, 'mesh')
meshTag.set('name', node.name + mesh.name_full)
meshTag.set('num_vertex_pos', str(numVertexPos))
meshTag.set('num_faces', str(numFaces))
meshTag.set('num_vertex_groups', str(numGroups))
meshTag.set('num_shape_keys', str(numShapeKeys))
+17 -77
View File
@@ -1,20 +1,19 @@
#include "glad.h"
#include <glfw3.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include "shader.h"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "shader.h"
#include "assetManager.h"
using namespace std;
using namespace glm;
namespace vb01{
Shader::Shader(string shaderPath, bool geometry){
this->geometry = geometry;
this->path = shaderPath;
initShaders(shaderPath + ".vert", shaderPath + ".frag", shaderPath + ".geo");
loadShaders();
@@ -22,7 +21,6 @@ namespace vb01{
Shader::Shader(string vertShader, string fragShader){
this->geometry = false;
this->path = vertShader;
initShaders(vertShader, fragShader, "");
loadShaders();
@@ -30,88 +28,30 @@ namespace vb01{
Shader::Shader(string vertShader, string fragShader, string geoShader){
this->geometry = true;
this->path = vertShader;
initShaders(vertShader, fragShader, geoShader);
loadShaders();
}
Shader::~Shader(){}
string Shader::getName(){
int dirId = path.find_last_of('/');
string name = (dirId != -1 ? path.substr(dirId + 1) : path);
int dirId = vString->path.find_last_of('/');
string name = (dirId != -1 ? vString->path.substr(dirId + 1) : vString->path);
int dotId = path.find_last_of('.');
int dotId = name.find_last_of('.');
if(dotId != -1)
name = name.substr(0, dotId);
if(dotId != -1)
name = name.substr(0, dotId);
return name;
return name;
}
void Shader::initShaders(string vertShaderPath, string fragShaderPath, string geoShaderPath){
ifstream vertShaderFile, fragShaderFile;
vertShaderFile.open(vertShaderPath);
fragShaderFile.open(fragShaderPath);
stringstream vertShaderStream, fragShaderStream;
vertShaderStream << vertShaderFile.rdbuf();
fragShaderStream << fragShaderFile.rdbuf();
vertShaderFile.close();
fragShaderFile.close();
vString = vertShaderStream.str();
fString = fragShaderStream.str();
AssetManager *am = AssetManager::getSingleton();
vString = (ShaderAsset*)am->getAsset(vertShaderPath);
fString = (ShaderAsset*)am->getAsset(fragShaderPath);
if(geometry){
ifstream geoShaderFile;
geoShaderFile.open(geoShaderPath);
stringstream geoShaderStream;
geoShaderStream << geoShaderFile.rdbuf();
geoShaderFile.close();
gString = geoShaderStream.str();
}
}
void Shader::editShader(ShaderType type, int line, string insertion){
replaceLine(type, line, insertion);
loadShaders();
}
void Shader::replaceLine(ShaderType type, int line, string insertion){
string *shaderString;
switch(type){
case VERTEX_SHADER:
shaderString = &vString;
break;
case FRAGMENT_SHADER:
shaderString = &fString;
break;
case GEOMETRY_SHADER:
shaderString = &gString;
break;
}
int numPassedLines = 0, lineStart = -1, lineEnd = -1;
for(int i = 0; i < shaderString->length(); i++)
if(shaderString[0][i] == '\n'){
if(numPassedLines == line - 1)
lineStart = i + 1;
if(numPassedLines == line){
lineEnd = i;
break;
}
numPassedLines++;
}
*shaderString = shaderString->substr(0, lineStart) + insertion + shaderString->substr(lineEnd);
if(geometry)
gString = (ShaderAsset*)am->getAsset(geoShaderPath);
}
void Shader::pushShader(u32 &type, string &sString, int glType, ErrorType errorType){
@@ -124,11 +64,11 @@ namespace vb01{
void Shader::loadShaders(){
u32 vert, geo, frag;
pushShader(vert, vString, GL_VERTEX_SHADER, VERTEX_ERROR);
pushShader(frag, fString, GL_FRAGMENT_SHADER, FRAGMENT_ERROR);
pushShader(vert, vString->shaderString, GL_VERTEX_SHADER, VERTEX_ERROR);
pushShader(frag, fString->shaderString, GL_FRAGMENT_SHADER, FRAGMENT_ERROR);
if(geometry)
pushShader(geo, gString, GL_GEOMETRY_SHADER, GEOMETRY_ERROR);
pushShader(geo, gString->shaderString, GL_GEOMETRY_SHADER, GEOMETRY_ERROR);
id = glCreateProgram();
glAttachShader(id, vert);
+5 -5
View File
@@ -4,6 +4,7 @@
#include <string>
#include <glm/mat4x4.hpp>
#include "shaderAsset.h"
#include "vector.h"
#include "util.h"
@@ -17,10 +18,10 @@ namespace vb01{
Shader(std::string, bool = false);
Shader(std::string, std::string);
Shader(std::string, std::string, std::string);
~Shader();
~Shader(){}
std::string getName();
void setNumLights(int);
void use();
void loadShaders();
void setMat4(glm::mat4, std::string);
void setVec4(Vector4, std::string);
void setVec3(Vector3, std::string);
@@ -29,17 +30,16 @@ namespace vb01{
void setBool(bool, std::string);
void setInt(int, std::string);
void setUnsignedInt(u32, std::string);
void editShader(ShaderType, int, std::string);
void editShader(ShaderType, int, std::string){}
inline bool isGeometry(){return geometry;}
private:
void initShaders(std::string, std::string, std::string);
void replaceLine(ShaderType, int, std::string);
void loadShaders();
void pushShader(u32&, std::string&, int, ErrorType);
void checkCompileErrors(u32, ErrorType);
u32 id;
bool geometry = false;
std::string path, vString, fString, gString;
ShaderAsset *vString = nullptr, *fString = nullptr, *gString = nullptr;
friend class ShaderTest;
};
+17
View File
@@ -0,0 +1,17 @@
#ifndef SHADER_ASSET_H
#define SHADER_ASSET_H
#include "asset.h"
namespace vb01{
struct ShaderAsset : public Asset{
std::string shaderString = "";
ShaderAsset(std::string p, std::string str){
path = p;
shaderString = str;
}
};
}
#endif
+30
View File
@@ -0,0 +1,30 @@
#include "shaderReader.h"
#include "shaderAsset.h"
#include <sstream>
#include <fstream>
namespace vb01{
using namespace std;
static ShaderReader *shaderReader = nullptr;
ShaderReader* ShaderReader::getSingleton(){
if(!shaderReader)
shaderReader = new ShaderReader();
return shaderReader;
}
Asset* ShaderReader::readAsset(string path){
ifstream shaderFile;
shaderFile.open(path);
stringstream shaderStream;
shaderStream << shaderFile.rdbuf();
shaderFile.close();
return new ShaderAsset(path, shaderStream.str());
}
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef SHADER_READER_H
#define SHADER_READER_H
#include "abstractAssetReader.h"
namespace vb01{
class ShaderReader : public AbstractAssetReader{
public:
static ShaderReader* getSingleton();
Asset* readAsset(std::string);
private:
ShaderReader(){}
};
}
#endif
+12 -9
View File
@@ -60,6 +60,16 @@ namespace vb01{
}
}
void Texture::loadImageData(ImageAsset *asset, int i){
width = asset->width;
height = asset->height;
glGenTextures(1, &texture[i]);
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTexImage2D(GL_TEXTURE_2D, 0, png ? GL_RGBA : GL_RGB, width, height, 0, png ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, asset->image);
glGenerateMipmap(GL_TEXTURE_2D);
}
void Texture::create2DTexture(bool flip){
mixRatio = .1;
@@ -69,19 +79,12 @@ namespace vb01{
if(paths[i].substr(length - 4, string::npos) == ".png")
png = true;
glGenTextures(1, &texture[i]);
glBindTexture(GL_TEXTURE_2D, texture[i]);
loadImageData((ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
ImageAsset *asset = (ImageAsset*)AssetManager::getSingleton()->getAsset(paths[i]);
width = asset->width;
height = asset->height;
glTexImage2D(GL_TEXTURE_2D, 0, png ? GL_RGBA : GL_RGB, width, height, 0, png ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, asset->image);
glGenerateMipmap(GL_TEXTURE_2D);
}
}
+44 -14
View File
@@ -15,10 +15,11 @@ layout (location = 1) out vec4 BrightColor;
//0-POINT,1-DIRECTIONAL,2-SPOT
struct Light{
int type;
bool useAngle, additive, render;
int type, attenuation;
vec3 pos, color, direction;
float innerAngle, outerAngle;
float a, b, c, near, far;
float a, b, c, near, far, radius;
sampler2D depthMap;
samplerCube depthMapCube;
mat4 lightMat;
@@ -33,7 +34,7 @@ struct Texture{
uniform Texture textures[4];
uniform samplerCube environmentMap;
uniform Light lights[numLights];
uniform bool lightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled;
uniform bool lightingEnabled, constLightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled;
uniform vec4 diffuseColor, specularColor;
uniform float shinyness, specularStrength;
uniform vec3 camPos;
@@ -96,17 +97,38 @@ void main(){
vec3 diffuseCol = vec3(0), specularCol = vec3(0);
if(checkLights){
bool addedLighting = false;
for(int i = 0; i < numLights; i++){
if(!lights[i].render) continue;
vec3 lightDir = vec3(0), viewDir = normalize(camPos - fragPos);
float attenuation = 1.0;
float a = lights[i].a, b = lights[i].b, c = lights[i].c, dist = length(fragPos - lights[i].pos), factor, coef = 1;
float attenuation = 1, coef = 1;
float factor = 0;
bool canAdd = false;
if(lights[i].type == 0){
lightDir = normalize(lights[i].pos - fragPos);
attenuation = 1.0 / (a * dist * dist + b * dist + c);
float dist = length(lights[i].pos - fragPos), radius = lights[i].radius;
if(lights[i].attenuation == 0){
float a = lights[i].a, b = lights[i].b, c = lights[i].c;
attenuation = 1.0 / (a * dist * dist + b * dist + c);
factor = (lights[i].useAngle ? max(dot(lightDir, normalize(normal)), 0.) : 1) * attenuation;
}
else if(lights[i].attenuation == 1 && dist < radius && radius > 0){
canAdd = !lights[i].additive;
factor = 1.0 - dist / lights[i].radius;
}
else if(lights[i].attenuation == 2 && dist < radius && radius > 0){
canAdd = !lights[i].additive;
factor = 1;
}
}
else if(lights[i].type == 1)
else if(lights[i].type == 1){
lightDir = -normalize(lights[i].direction);
factor = max(dot(lightDir, normalize(normal)), 0.) * attenuation;
}
else if(lights[i].type == 2){
lightDir = normalize(lights[i].pos - fragPos);
float innerAngle = lights[i].innerAngle;
@@ -118,10 +140,18 @@ void main(){
if(angle > lights[i].outerAngle)
continue;
}
factor = max(dot(lightDir, normal), 0.);
diffuseCol += lights[i].color * (factor * attenuation * coef);
factor = max(dot(lightDir, normalize(normal)), 0.) * attenuation * coef;
}
else factor = 1;
if(lights[i].additive)
diffuseCol += lights[i].color * factor;
else if(!lights[i].additive && constLightingEnabled && !addedLighting && canAdd){
addedLighting = true;
diffuseCol += lights[i].color * factor;
}
if(specularMapEnabled){
float specularSample = texture(textures[2].pastTexture, texCoords).r;
@@ -130,12 +160,12 @@ void main(){
specularCol += specularStrength * spec * specularSample * lights[i].color;
}
float shadow = getShadow(i);
diffuseCol *= (1.0 - shadow);
if(castShadow)
diffuseCol *= (1.0 - getShadow(i));
}
finalColor *= vec4(diffuseCol + specularCol, 1);
}
finalColor *= vec4(diffuseCol + specularCol, 1);
}
float brightness = dot(finalColor.rgb, vec3(0.2126, 0.7152, 0.0722));
+3
View File
@@ -10,6 +10,8 @@
#include FT_FREETYPE_H
namespace vb01{
struct ImageAsset;
class Texture : public Animatable{
public:
~Texture();
@@ -20,6 +22,7 @@ namespace vb01{
void select(int = 0, int = 0);
void update(int = 0);
void animate(float, KeyframeChannel);
void loadImageData(ImageAsset*, int = 0);
inline u32* getTexture(int i = 0){return &(texture[i]);}
inline std::string* getPath(){return paths;}
inline int getNumFrames(){return numFrames;}
+11
View File
@@ -90,4 +90,15 @@ namespace vb01{
return str;
}
int findNthOccurence(string &str, string occ, int occId, bool forward){
int occurenceId = (forward ? str.find(occ) : str.rfind(occ)), iteration = 0;
while(occurenceId != -1 && iteration != occId){
occurenceId = (forward ? str.find(occ, occurenceId + 1) : str.rfind(occ, occurenceId - 1));
iteration++;
}
return occurenceId;
}
}
+1
View File
@@ -23,6 +23,7 @@ namespace vb01{
void readFile(std::string, std::vector<std::string>&, int = 0, int = -1);
void getLineData(std::string, std::string[], int, int = 0);
int findNthOccurence(std::string&, std::string, int, bool = true);
int getCharId(std::string, char, bool = false);
std::wstring stringToWstring(std::string str);
std::string wstringToString(std::wstring wstr);
+75 -48
View File
@@ -42,6 +42,8 @@ namespace vb01{
assetRootNode->getDescendants(descendants);
setupDrivers(descendants);
delete doc;
return asset;
}
@@ -57,41 +59,61 @@ namespace vb01{
}
}
//TODO remove the 4 literal for bone weights and indices
Mesh* XmlModelReader::processMesh(XMLElement *meshEl){
vector<Vector3> vertPos, vertNorm;
vector<float> weights;
int numVertPos = atoi(meshEl->Attribute("num_vertex_pos"));
int numVertexGroups = atoi(meshEl->Attribute("num_vertex_groups"));
const char *tagName = "vertdata";
for(XMLElement *vertEl = meshEl->FirstChildElement(tagName); vertEl && strcmp(vertEl->Name(), tagName) == 0; vertEl = vertEl->NextSiblingElement()){
Vector3 *vertPos = new Vector3[numVertPos];
float **weights = new float*[numVertPos];
int **boneIndices = new int*[numVertPos], i = 0;
for(XMLElement *vertEl = meshEl->FirstChildElement(tagName); vertEl && strcmp(vertEl->Name(), tagName) == 0, i < numVertPos; vertEl = vertEl->NextSiblingElement(), i++){
float posX = atof(vertEl->Attribute("px"));
float posY = atof(vertEl->Attribute("py"));
float posZ = atof(vertEl->Attribute("pz"));
vertPos.push_back(Vector3(posX, posY, posZ));
vertPos[i] = Vector3(posX, posY, posZ);
float normX = atof(vertEl->Attribute("nx"));
float normY = atof(vertEl->Attribute("ny"));
float normZ = atof(vertEl->Attribute("nz"));
vertNorm.push_back(Vector3(normX, normY, normZ));
weights[i] = new float[4];
boneIndices[i] = new int[4];
for(XMLElement *weightEl = vertEl->FirstChildElement("weight"); weightEl; weightEl = weightEl->NextSiblingElement())
weights.push_back(atof(weightEl->Attribute("value")));
for(int j = 0; j < 4; j++){
weights[i][j] = 0;
boneIndices[i][j] = -1;
}
int boneIndex = 0, j = 0;
for(XMLElement *weightEl = vertEl->FirstChildElement("weight"); weightEl, j < numVertexGroups; weightEl = weightEl->NextSiblingElement(), j++){
float w = atof(weightEl->Attribute("value"));
if(w > 0){
weights[i][boneIndex] = w;
boneIndices[i][boneIndex] = j;
boneIndex++;
}
}
}
int numVertexGroups = atoi(meshEl->Attribute("num_vertex_groups"));
string *vertexGroups = new string[numVertexGroups];
tagName = "vertexgroup";
int i = 0;
i = 0;
for(XMLElement *vertGroupEl = meshEl->FirstChildElement(tagName); vertGroupEl && strcmp(vertGroupEl->Name(), tagName) == 0; vertGroupEl = vertGroupEl->NextSiblingElement(), i++)
vertexGroups[i] = (vertGroupEl->Attribute("name"));
if(numVertexGroups > 0)
for(XMLElement *vertGroupEl = meshEl->FirstChildElement(tagName); vertGroupEl && strcmp(vertGroupEl->Name(), tagName) == 0 && i < numVertexGroups; vertGroupEl = vertGroupEl->NextSiblingElement(), i++)
vertexGroups[i] = vertGroupEl->Attribute("name");
i = 0;
int numVertices = 3 * atoi(meshEl->Attribute("num_faces"));
MeshData::Vertex *vertices = new MeshData::Vertex[numVertices];
tagName = "vert";
vector<u32> vertIds;
u32 *indices = new u32[numVertices];
Vector3 *normals = new Vector3[numVertices];
vector<int> vertIds;
for(XMLElement *vertEl = meshEl->FirstChildElement(tagName); vertEl && strcmp(vertEl->Name(), tagName) == 0; vertEl = vertEl->NextSiblingElement(), i++){
int id = atoi(vertEl->Attribute("id"));
vertIds.push_back(id);
@@ -110,60 +132,65 @@ namespace vb01{
float biTanZ = atof(vertEl->Attribute("bz"));
Vector3 biTan = Vector3(biTanX, biTanY, biTanZ);
normals[i] = biTan.cross(tan);
MeshData::Vertex vertex;
vertex.pos = vertPos[id];
vertex.norm = vertNorm[id];
vertex.pos = &vertPos[id];
vertex.norm = &normals[id];
vertex.uv = uv;
vertex.tan = tan;
vertex.biTan = biTan;
for(int j = 0, boneIndex = 0; j < numVertexGroups; j++){
if(weights[id * numVertexGroups + j] > 0){
vertex.boneIndices[boneIndex] = j;
vertex.weights[boneIndex] = weights[id * numVertexGroups + j];
boneIndex++;
}
}
vertex.weights = weights[id];
vertex.boneIndices = boneIndices[id];
indices[i] = i;
vertices[i] = vertex;
}
vertNorm.clear();
tagName = "shapekey";
i = 0;
int numShapeKeys = atoi(meshEl->Attribute("num_shape_keys"));
MeshData::ShapeKey *shapeKeys = new MeshData::ShapeKey[numShapeKeys];
MeshData::ShapeKey *shapeKeys = nullptr;
Vector3 **shapeKeyOffsets = nullptr;
for(XMLElement *shapeKeyEl = meshEl->FirstChildElement(tagName); shapeKeyEl && strcmp(shapeKeyEl->Name(), tagName) == 0; shapeKeyEl = shapeKeyEl->NextSiblingElement(), i++){
string name = shapeKeyEl->Attribute("name");
float minValue = atof(shapeKeyEl->Attribute("min"));
float maxValue = atof(shapeKeyEl->Attribute("max"));
shapeKeys[i] = MeshData::ShapeKey(name, minValue, minValue, maxValue);
if(numShapeKeys > 0){
shapeKeys = new MeshData::ShapeKey[numShapeKeys];
shapeKeyOffsets = new Vector3*[numVertPos];
XMLElement *driverEl = shapeKeyEl->FirstChildElement("driver");
KeyframeChannel channel = processKeyframeChannells(driverEl)[0];
const char *nodeName = driverEl->Attribute("obj");
const char *boneName = driverEl->Attribute("bone");
Driver::VariableType type = Driver::getDriverVariableType(driverEl->Attribute("type"));
driversByNodeNames.push_back(make_pair(string(nodeName) + (boneName ? "." + string(boneName) : ""), new Driver(&shapeKeys[i], channel, type)));
for(int i = 0; i < numVertPos; i++)
shapeKeyOffsets[i] = new Vector3[100];
vector<Vector3> shapeKeyPos;
for(XMLElement *shapeKeyEl = meshEl->FirstChildElement(tagName); shapeKeyEl && strcmp(shapeKeyEl->Name(), tagName) == 0 && i < numShapeKeys; shapeKeyEl = shapeKeyEl->NextSiblingElement(), i++){
string name = shapeKeyEl->Attribute("name");
float minValue = atof(shapeKeyEl->Attribute("min"));
float maxValue = atof(shapeKeyEl->Attribute("max"));
shapeKeys[i] = MeshData::ShapeKey(name, minValue, minValue, maxValue);
for(XMLElement *vertEl = shapeKeyEl->FirstChildElement("vert"); vertEl; vertEl = vertEl->NextSiblingElement()){
float posX = atof(vertEl->Attribute("px"));
float posY = atof(vertEl->Attribute("py"));
float posZ = atof(vertEl->Attribute("pz"));
shapeKeyPos.push_back(Vector3(posX, posY, posZ));
}
XMLElement *driverEl = shapeKeyEl->FirstChildElement("driver");
KeyframeChannel channel = processKeyframeChannells(driverEl)[0];
const char *nodeName = driverEl->Attribute("obj");
const char *boneName = driverEl->Attribute("bone");
Driver::VariableType type = Driver::getDriverVariableType(driverEl->Attribute("type"));
driversByNodeNames.push_back(make_pair(string(nodeName) + (boneName ? "." + string(boneName) : ""), new Driver(&shapeKeys[i], channel, type)));
for(int j = 0; j < numVertices; j++)
vertices[j].shapeKeyOffsets[i] = shapeKeyPos[vertIds[j]] - vertPos[vertIds[j]];
int j = 0;
for(XMLElement *vertEl = shapeKeyEl->FirstChildElement("vert"); vertEl; vertEl = vertEl->NextSiblingElement(), j++){
float posX = atof(vertEl->Attribute("px"));
float posY = atof(vertEl->Attribute("py"));
float posZ = atof(vertEl->Attribute("pz"));
shapeKeyOffsets[j][i] = Vector3(posX, posY, posZ) - vertPos[j];
}
}
for(int i = 0; i < numVertices; i++)
vertices[i].shapeKeyOffsets = shapeKeyOffsets[vertIds[i]];
}
const char *fullSkeletonName = meshEl->Attribute("skeleton");
string name = string(meshEl->Parent()->ToElement()->Attribute("name")) + string(meshEl->Attribute("name"));
Mesh *mesh = new Mesh(MeshData(vertices, indices, numVertices / 3, name, vertexGroups, numVertexGroups, (fullSkeletonName ? fullSkeletonName : ""), shapeKeys, numShapeKeys));
Mesh *mesh = new Mesh(MeshData(vertPos, weights, boneIndices, shapeKeyOffsets, numVertPos, normals, vertices, indices, numVertices / 3, name, vertexGroups, numVertexGroups, (fullSkeletonName ? fullSkeletonName : ""), shapeKeys, numShapeKeys));
return mesh;
}
@@ -291,7 +318,7 @@ namespace vb01{
XMLElement *meshTag = xmlEl->FirstChildElement("mesh");
if(meshTag)
node->attachMesh(processMesh(meshTag));
node->attachMesh(processMesh(meshTag));
XMLElement *lightTag = xmlEl->FirstChildElement("light");