diff --git a/CMakeLists.txt b/CMakeLists.txt index 341c8e5..582c541 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,8 @@ set(CMAKE_CXX_STANDARD 20) file(GLOB_RECURSE HEADERS "include/*.h") file(GLOB_RECURSE SOURCES "src/*.cpp") +include_directories("include" ${J3ML_SOURCE_DIR}/include) + if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) message(FATAL_ERROR "In-Source builds are not allowed") endif() @@ -31,12 +33,9 @@ if (WIN32) add_library(Collage STATIC ${SOURCES} ${HEADERS}) endif() -target_include_directories(Collage PUBLIC ${PROJECT_SOURCE_DIR}/include ${J3ML_SOURCE_DIR}/include) - add_executable(CollageTest main.cpp) set_target_properties(Collage PROPERTIES LINKER_LANGUAGE CXX) target_link_libraries(Collage PUBLIC J3ML) - target_link_libraries(CollageTest PUBLIC Collage) set_target_properties(CollageTest PROPERTIES LINKER_LANGUAGE CXX) \ No newline at end of file diff --git a/include/Collage/types/animation.h b/include/Collage/types/animation.h index ee21f01..ed53255 100644 --- a/include/Collage/types/animation.h +++ b/include/Collage/types/animation.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include struct KeyFrame { @@ -8,21 +7,4 @@ struct KeyFrame { Bone bone; }; -class Animation { -public: - std::string name; - float deltaBetweenKeyFrames; - std::vector keyFrames; -}; - -class AnimationState { //Information which would be stored on each animated entity. -protected: - Animation* animation = nullptr; -public: - std::vector* animations; //Will point to the list of animations on the model. - std::chrono::high_resolution_clock::time_point start; //When the current animation was started. - [[nodiscard]] float animationTime() const; //The amount of time in ms that the animation has been running for. - Animation* getAnimation(); - void setAnimation(Animation* anim); - void reset(); -}; \ No newline at end of file +typedef std::vector Animation; \ No newline at end of file diff --git a/include/Collage/types/bone.h b/include/Collage/types/bone.h index 510d466..aecf3bf 100644 --- a/include/Collage/types/bone.h +++ b/include/Collage/types/bone.h @@ -5,11 +5,10 @@ class Bone { protected: std::string name; Matrix4x4 matrix; - //float weight; + float weight; Bone* parent; std::vector children; public: - int index; bool isRootBone(); bool hasChildren(); const Matrix4x4& getMatrix(); @@ -17,11 +16,7 @@ public: void appendChild(const Bone& bone); unsigned int getDepth(); //The "depth" refers to how far in the bone is on the bonemap. For ex, the fingers would be deeper than the elbow. Bone* getParent(); - void setParent(Bone* b); Bone* getChildByName(const std::string& bName); Bone* getChildByNameRecursive(const std::string& bName); - Bone* getChildByIndexRecursive(int i); Bone* getFirstChild(); - const std::string& getName(); - void setName(const std::string& n); }; \ No newline at end of file diff --git a/include/Collage/types/model.h b/include/Collage/types/model.h index de22801..7e325b7 100644 --- a/include/Collage/types/model.h +++ b/include/Collage/types/model.h @@ -1,13 +1,13 @@ #pragma once #include -#include +#include +#include #include #include +#include #include -#include typedef Vector3 Vertex; -typedef Vector3 TextureCoordinate; enum struct ModelType : uint8_t { WAVEFRONT_OBJ = 0, @@ -16,32 +16,35 @@ enum struct ModelType : uint8_t { COLLADA = 3, //*Very* complicated. }; +struct FaceIndices { + unsigned int vertexIndex[3]; + unsigned int texCoordIndex[3]; +}; + +class SkeletalVertex : public Vertex { + int8_t joints[3]; //The index of 4 bones that can effect the vertex. 0 represents an empty slot. -1 represents the root bone. + Vector4 weights; //The 4 weights must total to 1.0 +}; + class Model { protected: void load(const std::string& file); void loadOBJ(const std::string& filename); - void loadAMO(const std::string& filename); -public: - std::string name; - ModelType type; std::vector vertices; std::vector indices; - std::vector textureCoords; - //std::vector textureInfo; + std::vector textureInfo; +public: + ModelType type; + const std::vector& getVertices(); + const std::vector& getIndices(); + const std::vector& getTextureInformation(); Model() = default; explicit Model(const std::string& file); }; -class SkeletalVertex : public Vertex { -public: - std::vector bones; //The index of bones that can effect the vertex. 0 represents an empty slot. -1 represents the root bone. - std::vector weights; -}; - class SkeletalModel : public Model { protected: - void loadAMO(const std::string& filename); -public: std::vector vertices; - Bone boneMap; -}; +public: + std::vector& getSkeletalVertices(); +}; \ No newline at end of file diff --git a/main.cpp b/main.cpp index aae7c6e..f4be74a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,4 @@ -#include +#include int main() { - Model m = Model("chicken.amo"); } diff --git a/src/amo.cpp b/src/amo.cpp deleted file mode 100644 index 20489f8..0000000 --- a/src/amo.cpp +++ /dev/null @@ -1,678 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/* - * This is unfinished and janky as shit. You have been warned. - * - * Currently values are parsed into temporary structs until we - * figure out what to do with them. The animation parsing is - * particularly fucked right now. There's plans to do more - * cleanup later when we throw this all at the game engine. - * - * I hope for us to be able to load the chicken into the - * engine soon. - * - * - Maxine Hayes - * - * p.s perhaps stringers are a good idea for exporting. - */ - -struct Frame { - int id; - std::vector n; -}; - -void operator>>(std::istream& in, Frame& q) { - in >> q.id; - - int i; - for (i=0; i<7; i++) { - float v; - in >> v; - q.n.push_back(v); - } -} - -struct KeyFrame { - float start; - int frame_cnt; -}; - -void operator>>(std::istream& in, KeyFrame& q) { - // throw away prefix - std::string p; - in >> p; - - in >> q.start; - in >> q.frame_cnt; -} - -struct FrameSet { - KeyFrame k; - std::vector f; -}; - -FrameSet parse_fs(std::istringstream& s, std::ifstream& f) { - FrameSet fs; - s >> fs.k; - - int i; - for (i=0; i> frame; - - fs.f.push_back(frame); - } else { - break; - } - } - - return fs; -} - - -/* -void operator>>(std::istream& in, FrameSet& q) { - in >> q.k; - - int i; - for (i=0; i> f; - q.f.push_back(f); - } -} -*/ - -struct Animation_Meta { - std::string name; - int duration; - int keyframe_cnt; -}; - -void operator>>(std::istream& in, Animation_Meta& q) { - // throw away prefix - std::string p; - in >> p; - - in >> q.name; - in >> q.duration; - in >> q.keyframe_cnt; -} - -struct Animation { - Animation_Meta meta; - std::vector fs; -}; - -// Parse animations -std::vector parse_a(std::istringstream& s, std::ifstream& f) { - int acnt; - s >> acnt; - std::cout << "a " << acnt << std::endl; - - std::vector a; - - int i; - for (i=0; i> animation.meta; - - int i; - for (i=0; i n; -}; - -void operator>>(std::istream& in, Joint& q) { - in >> q.name >> q.x; - - int i; - for (i=0; i<16; i++) { - float f; - in >> f; - q.n.push_back(f); - } -} - -// Parse joints -std::vector parse_j(std::istringstream& s, std::ifstream& f) { - // get count - int jcnt; - s >> jcnt; - std::cout << "j " << jcnt << std::endl; - - // return later - std::vector js; - - // parse lines until count - int i; - for (i=0; i> j; - - js.push_back(j); - } else { - break; - } - } - - return js; -} - -struct Face { - std::vector n; -}; - -void operator>>(std::istream& in, Face& q) { - int i; - for (i=0; i<15; i++) { - int v; - in >> v; - q.n.push_back(v); - } -} - -// Parse faces -std::vector parse_f(std::istringstream& s, std::ifstream& f) { - // get count - int facescnt; - s >> facescnt; - std::cout << "f " << facescnt << std::endl; - - // return later - std::vector faces; - - // parse until count - int i; - for (i=0; i> face; - - faces.push_back(face); - } else { - break; - } - } - - return faces; -} - -struct Vweight { - std::vector n; -}; - -void operator>>(std::istream& in, Vweight& q) { - int i; - for (i=0; i<4; i++) { - float v; - in >> v; - q.n.push_back(v); - } -} - -// Parse vertex weights -std::vector parse_vw(std::istringstream& s, std::ifstream& f) { - // get count - int vwcnt; - s >> vwcnt; - std::cout << "vw " << vwcnt << std::endl; - - // return later - std::vector vw; - - // parse lines until count - int i; - for (i=0; i> vweight; - - vw.push_back(vweight); - } else { - break; - } - } - - return vw; -} - -struct Vjoint { - std::vector n; -}; - -void operator>>(std::istream& in, Vjoint& q) { - int i; - for (i=0; i<4; i++) { - int v; - in >> v; - q.n.push_back(v); - } -} - -// Parse vertex joints -std::vector parse_vj(std::istringstream& s, std::ifstream& f) { - // get count - int vjcnt; - s >> vjcnt; - std::cout << "vj " << vjcnt << std::endl; - - // return later - std::vector vj; - - // parse lines until count - int i; - for (i=0; i> vjoint; - - vj.push_back(vjoint); - } else { - break; - } - } - - return vj; -} - -struct Vnormal { - std::vector n; -}; - -void operator>>(std::istream& in, Vnormal& q) { - int i; - for (i=0; i<3; i++) { - float v; - in >> v; - q.n.push_back(v); - } -} - -// Parse vertex normals -std::vector parse_vn(std::istringstream& s, std::ifstream& f) { - // get count - int vncnt; - s >> vncnt; - std::cout << "vn " << vncnt << std::endl; - - // return later - std::vector vn; - - // parse lines until count - int i; - for (i=0; i> vnormal; - - vn.push_back(vnormal); - } else { - break; - } - } - - return vn; -} - -struct Vtexture { - std::vector n; -}; - -void operator>>(std::istream& in, Vtexture& q) { - int i; - for (i=0; i<2; i++) { - float v; - in >> v; - q.n.push_back(v); - } -} - -// Parse vertex textures -std::vector parse_vt(std::istringstream& s, std::ifstream& f) { - // get count - int vtcnt; - s >> vtcnt; - std::cout << "vt " << vtcnt << std::endl; - - // return later - std::vector vt; - - // parse until count - int i; - for (i=0; i> vtexture; - - vt.push_back(vtexture); - } else { - break; - } - } - - return vt; -} - -struct Vertice { - std::vector n; -}; - -void operator>>(std::istream& in, Vertice& q) { - int i; - for (i=0; i<3; i++) { - float v; - in >> v; - q.n.push_back(v); - } -} - -// Parse vertices -std::vector parse_v(std::istringstream& s, std::ifstream& f) { - // get count - int vcnt; - s >> vcnt; - std::cout << "v " << vcnt << std::endl; - - // return later - std::vector v; - - // parses lines until count - int i; - for (i=0; i> vertice; - - v.push_back(vertice); - } else { - break; - } - } - - return v; -} - -// Parse Animated Object -std::tuple parse_ao(std::istringstream& s) { - std::string name; - int statecnt; - s >> name >> statecnt; - return {name, statecnt}; -} - -void Model::loadAMO(const std::string& filename) { - // Print filename - std::cout << filename << std::endl; - - // Create ifstream from AMO file - std::ifstream file(filename); - - std::string line; - while (getline(file, line)) { - // Get prefix - std::istringstream stream(line); - std::string prefix; - stream >> prefix; - - if (prefix == "ao") { - std::tuple r; - r = parse_ao(stream); - std::cout << get<0>(r) << " " << get<1>(r) << std::endl; - } else if (prefix == "v") { - std::vector v; - v = parse_v(stream, file); - for (const Vertice& i: v) { - for (const float& ii: i.n) { - std::cout << ii << " "; - } - std::cout << std::endl; - } - } else if (prefix == "vt") { - std::vector vt; - vt = parse_vt(stream, file); - for (const Vtexture& i: vt) { - for (const float& ii: i.n) { - std::cout << ii << " "; - } - std::cout << std::endl; - } - } else if (prefix == "vn") { - std::vector vn; - vn = parse_vn(stream, file); - for (const Vnormal& i: vn) { - for (const float& ii: i.n) { - std::cout << ii << " "; - } - std::cout << std::endl; - } - } else if (prefix == "vj") { - std::vector vj; - vj = parse_vj(stream, file); - for (const Vjoint& i: vj) { - for (const int& ii: i.n) { - std::cout << ii << " "; - } - std::cout << std::endl; - } - - } else if (prefix == "vw") { - std::vector vw; - vw = parse_vw(stream, file); - for (const Vweight& i: vw) { - for (const float& ii: i.n) { - std::cout << ii << " "; - } - std::cout << std::endl; - } - } else if (prefix == "f") { - std::vector faces; - faces = parse_f(stream, file); - for (const Face& i: faces) { - for (const int& ii: i.n) { - std::cout << ii << " "; - } - std::cout << std::endl; - } - } else if (prefix == "j") { - std::vector j; - j = parse_j(stream, file); - for (const Joint& i: j) { - std::cout << i.name << " " << i.x << " "; - for (const float& ii: i.n) { - std::cout << ii << " "; - } - std::cout << std::endl; - } - } else if (prefix == "a") { - std::vector a; - a = parse_a(stream, file); - for (const Animation& i: a) { - std::cout << i.meta.name << " " << i.meta.duration << " " << i.meta.keyframe_cnt << std::endl; - for (const FrameSet& ii: i.fs) { - std::cout << "k " << ii.k.start << " " << ii.k.frame_cnt << std::endl; - for (const Frame& iii: ii.f) { - std::cout << "FRAME " << iii.id << " "; - - for (const float& iiii: iii.n) { - std::cout << iiii << " "; - } - std::cout << std::endl; - } - } - } - } - } - - file.close(); -} - -/* -void Model::loadAMO(const std::string& filename) { - std::cout << filename << std::endl; - std::ifstream file(filename); - std::vector positions; - std::vector uvs; - TextureInformation tInfo = {}; - std::string line; - while (std::getline(file, line)) { - std::istringstream stream(line); - std::string prefix; - stream >> prefix; - - // Animated Object - if (prefix == "ao") { - std::string name; - int statecnt; - stream >> name >> statecnt; - std::cout << "ao " << name << " " << statecnt << std::endl; - // Vertices Count - } else if (prefix == "v") { - int vcnt; - stream >> vcnt; - std::cout << "v " << vcnt << std::endl; - for (int i=0; i<=vcnt; i++) { - Vector3 v; - v = parse_v(stream); - std::cout << v.x << " " << v.y << " " << v.z << std::endl; - } - // Vertex Texture Count - } else if (prefix == "vt") { - int vtcnt; - stream >> vtcnt; - std::cout << "vt " << vtcnt << std::endl; - // Vertex Normals Count - } else if (prefix == "vn") { - int vncnt; - stream >> vncnt; - std::cout << "vn " << vncnt << std::endl; - // Vertex Joint Count - } else if (prefix == "vj") { - int vjcnt; - stream >> vjcnt; - std::cout << "vj " << vjcnt << std::endl; - // Vertex Weights Count - } else if (prefix == "vw") { - int vwcnt; - stream >> vwcnt; - std::cout << "vw " << vwcnt << std::endl; - // Faces Count - } else if (prefix == "f") { - int fcnt; - stream >> fcnt; - std::cout << "f " << fcnt << std::endl; - // Joints Count - } else if (prefix == "j") { - int jcnt; - stream >> jcnt; - std::cout << "j " << jcnt << std::endl; - // Animations Count - } else if (prefix == "a") { - int acnt; - stream >> acnt; - std::cout << "a " << acnt << std::endl; - // Start Animation Definition - } else if (prefix == "an") { - std::string aname; - int atimems; // Animation time in milliseconds - int n_interps; // Number of interpolations between key frames - stream >> aname >> atimems >> n_interps; - std::cout << "an " << aname << " " << atimems << " " << n_interps << std::endl; - // Animation Key Frame - } else if (prefix == "k") { - float kstart; // Timestamp of when key fram starts. - int n_movbones; // Number of moving bones. - stream >> kstart >> n_movbones; - std::cout << "k " << kstart << " " << n_movbones << std::endl; - // End - } else if (prefix == "end") { - std::cout << "End of AMO" << std::endl; - break; - } - } - file.close(); -} -*/ diff --git a/src/obj.cpp b/src/obj.cpp index cc8c9ef..7fe2861 100644 --- a/src/obj.cpp +++ b/src/obj.cpp @@ -1,9 +1,6 @@ -#include -#include +#include #include -//The OBJ *must* be exported as a triangle mesh and without normals. -//TODO support more options. void Model::loadOBJ(const std::string& filename) { std::ifstream file(filename); std::vector positions; @@ -31,6 +28,7 @@ void Model::loadOBJ(const std::string& filename) { vertexIndex[i]--; texCoordIndex[i]--; } + for (int i = 0; i < 3; ++i) { Vertex vertex; Vector2 textureCoordinate; @@ -42,7 +40,6 @@ void Model::loadOBJ(const std::string& filename) { } } } - //textureInfo.push_back(tInfo); // <- Fix yo shit + textureInfo.push_back(tInfo); file.close(); - type = ModelType::WAVEFRONT_OBJ; -}; +}; \ No newline at end of file diff --git a/src/types/animation.cpp b/src/types/animation.cpp index fb30a77..1e68caf 100644 --- a/src/types/animation.cpp +++ b/src/types/animation.cpp @@ -1,21 +1,2 @@ #include - -Animation* AnimationState::getAnimation() { - if (animation == nullptr) - throw std::runtime_error("There is no current animation."); - return animation; -} - -void AnimationState::setAnimation(Animation* anim) { - animation = anim; - start = std::chrono::high_resolution_clock::now(); -} - -void AnimationState::reset() { - animation = animations[0][0]; //The "idle" or "default" animation should *always* be in slot 0. - start = std::chrono::high_resolution_clock::now(); -} - -float AnimationState::animationTime() const { - return std::chrono::duration(std::chrono::high_resolution_clock::now() - start).count(); -} +#include \ No newline at end of file diff --git a/src/types/bone.cpp b/src/types/bone.cpp index 11ffd12..b284152 100644 --- a/src/types/bone.cpp +++ b/src/types/bone.cpp @@ -33,22 +33,12 @@ Bone* Bone::getChildByName(const std::string& bName) { for (auto& bone : children) if (bone->name == bName) return bone; - return nullptr; } -Bone* Bone::getChildByNameRecursive(const std::string& bName) { +Bone *Bone::getChildByNameRecursive(const std::string &bName) { if (children.empty()) return nullptr; - for (auto& bone : children) { - if (bone->name == bName) - return bone; - - Bone* result = bone->getChildByNameRecursive(bName); - if (result != nullptr) - return result; - } - return nullptr; } bool Bone::hasChildren() { @@ -77,29 +67,3 @@ unsigned int Bone::getDepth() { return depth; } -const std::string &Bone::getName() { - return name; -} - -void Bone::setName(const std::string &n) { - name = n; -} - -void Bone::setParent(Bone * b) { - parent = b; -} - -Bone* Bone::getChildByIndexRecursive(int ind) { - if (children.empty()) - return nullptr; - - for (auto& bone : children) { - if (bone->index == ind) - return bone; - - Bone* result = bone->getChildByIndexRecursive(ind); - if (result != nullptr) - return result; - } - return nullptr; -} diff --git a/src/types/model.cpp b/src/types/model.cpp index 8bcbc0e..e19532a 100644 --- a/src/types/model.cpp +++ b/src/types/model.cpp @@ -3,10 +3,24 @@ void Model::load(const std::string& file) { if (file.ends_with(".obj")) loadOBJ(file); - if (file.ends_with(".amo")) - loadAMO(file); +} + +const std::vector& Model::getVertices() { + return vertices; +} + +const std::vector& Model::getIndices() { + return indices; +} + +const std::vector& Model::getTextureInformation() { + return textureInfo; } Model::Model(const std::string &file) { load(file); } + +std::vector& SkeletalModel::getSkeletalVertices() { + return vertices; +}