From b06403ff323c02a19a2dc94adc485ea69e40133a Mon Sep 17 00:00:00 2001 From: bailwillharr Date: Fri, 16 Feb 2024 22:08:14 +0000 Subject: [PATCH] get tangent generation working again --- CMakeLists.txt | 2 + src/application.cpp | 2 +- src/libs/weldmesh.c | 194 ++++++++++++++++++++++++ src/libs/weldmesh.h | 49 ++++++ src/util/gltf_loader.cpp | 138 +++++++++++++++-- test/res/models/walls_with_tangents.glb | Bin 19253740 -> 19262724 bytes test/src/game.cpp | 32 ++-- 7 files changed, 392 insertions(+), 25 deletions(-) create mode 100644 src/libs/weldmesh.c create mode 100644 src/libs/weldmesh.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bd65870..6f6cf4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,8 @@ set(SRC_FILES "src/libs/stb_impl.cpp" "src/libs/tiny_gltf.h" "src/libs/tiny_gltf_impl.cpp" + "src/libs/weldmesh.c" + "src/libs/weldmesh.h" "src/renderer.cpp" "src/resources/font.cpp" "src/resources/material.cpp" diff --git a/src/application.cpp b/src/application.cpp index d4cbc8b..6de29d4 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -268,7 +268,7 @@ void Application::GameLoop() int depth = find_depth(i, 0); for (int j = 0; j < depth; ++j) tabs += std::string{" "}; ImGui::Text("%s%s", tabs.c_str(), t->tag.c_str()); - ImGui::Text("%.1f %.1f %.1f", t->position.x, t->position.y, t->position.z); + //ImGui::Text("%.1f %.1f %.1f", t->position.x, t->position.y, t->position.z); } } else { diff --git a/src/libs/weldmesh.c b/src/libs/weldmesh.c new file mode 100644 index 0000000..c39a61d --- /dev/null +++ b/src/libs/weldmesh.c @@ -0,0 +1,194 @@ +/** + * Copyright (C) 2011 by Morten S. Mikkelsen + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + + +#include "weldmesh.h" +#include +#include + +#ifdef __APPLE__ +#include /* OSX gets its malloc stuff through here */ +#else +#include +#endif + +static void MergeVertsFast(int * piCurNrUniqueVertices, int * piRemapTable, float * pfVertexDataOut, int * piVertexIDs, + const float pfVertexDataIn[], const int iNrVerticesIn, const int iFloatsPerVert, + const int iL_in, const int iR_in, const int iChannelNum); + +int WeldMesh(int * piRemapTable, float * pfVertexDataOut, + const float pfVertexDataIn[], const int iNrVerticesIn, const int iFloatsPerVert) +{ + int iUniqueVertices = 0, i=0; + int * piVertexIDs = NULL; + if(iNrVerticesIn<=0) return 0; + + + iUniqueVertices = 0; + piVertexIDs = (int *) malloc(sizeof(int)*iNrVerticesIn); + if(piVertexIDs!=NULL) + { + for(i=0; i=0); + } + + return iUniqueVertices; +} + + + + + +static void MergeVertsFast(int * piCurNrUniqueVertices, int * piRemapTable, float * pfVertexDataOut, int * piVertexIDs, + const float pfVertexDataIn[], const int iNrVerticesIn, const int iFloatsPerVert, + const int iL_in, const int iR_in, const int iChannelNum) +{ + const int iCount = iR_in-iL_in+1; + int l=0; + float fMin, fMax, fAvg; + assert(iCount>0); + // make bbox + fMin = pfVertexDataIn[ piVertexIDs[iL_in]*iFloatsPerVert + iChannelNum]; fMax = fMin; + for(l=(iL_in+1); l<=iR_in; l++) + { + const int index = piVertexIDs[l]*iFloatsPerVert + iChannelNum; + const float fVal = pfVertexDataIn[index]; + if(fMin>fVal) fMin=fVal; + else if(fMax=fMax || iCount==1) + { + if((iChannelNum+1) == iFloatsPerVert || iCount==1) // we are done, weld by hand + { + int iUniqueNewVertices = 0; + float * pfNewUniVertsOut = &pfVertexDataOut[ piCurNrUniqueVertices[0]*iFloatsPerVert ]; + + for(l=iL_in; l<=iR_in; l++) + { + const int index = piVertexIDs[l]*iFloatsPerVert; + + int iFound = 0; // didn't find copy yet. + int l2=0; + while(l2=iL_in && iL<=iR_in); + index = piVertexIDs[iL]*iFloatsPerVert+iChannelNum; + iReadyLeftSwap = !(pfVertexDataIn[index]=iL_in && iR<=iR_in); + index = piVertexIDs[iR]*iFloatsPerVert+iChannelNum; + iReadyRightSwap = pfVertexDataIn[index](lround(doubles[0] * 255.0)); + g = static_cast(lround(doubles[1] * 255.0)); + b = static_cast(lround(doubles[2] * 255.0)); + a = static_cast(lround(doubles[3] * 255.0)); + } + }; + //std::unordered_map> colour_textures; + std::vector> materials{}; materials.reserve(model.materials.size()); for (const tg::Material& material : model.materials) { @@ -182,11 +196,16 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic) } const auto& baseColorFactor4 = material.pbrMetallicRoughness.baseColorFactor; if (baseColorFactor4[0] != 1.0 || baseColorFactor4[1] != 1.0 || baseColorFactor4[2] != 1.0 || baseColorFactor4[3] != 1.0) { - LOG_WARN("Material {} contains a base color value which isn't supported yet.", material.name); if (material.pbrMetallicRoughness.baseColorTexture.index == -1) { - LOG_WARN("Material will be created with a white base color texture."); + LOG_INFO("Making color texture!"); + throw std::runtime_error("TODO"); + // convert double colors to integers + //Color col(baseColorFactor4.data()); + //if (colour_textures.contains(col)) { + // } } else { + LOG_WARN("Material {} contains a base color multiplier which isn't supported yet.", material.name); LOG_WARN("The material's base color texture will be used as-is."); } } @@ -243,6 +262,8 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic) const size_t num_vertices = pos_accessor.count; + bool generate_tangents = false; // generating tangents creates a new index list and therefore all attribute accessors must be reassigned + // these checks are probably unneccesary assuming a valid glTF file // if (pos_accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) throw std::runtime_error("Position att. must be float!"); // if (pos_accessor.type != 3) throw std::runtime_error("Position att. dim. must be 3!"); @@ -279,7 +300,7 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic) } else { // TODO: use MikkTSpace to generate tangents - throw std::runtime_error(std::string("No tangents found in primitive from ") + mesh.name); + generate_tangents = true; } // UV0 @@ -326,12 +347,104 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic) throw std::runtime_error(std::string("Invalid index buffer in primtive from: ") + mesh.name); } - // combine vertices into one array std::vector vertices; - vertices.reserve(num_vertices); - for (size_t i = 0; i < num_vertices; ++i) { - Vertex v{.pos = positions[i], .norm = normals[i], .tangent = tangents[i], .uv = uv0s[i]}; - vertices.push_back(v); + + if (generate_tangents) { + // generate tangents if they're not in the file + struct MeshData { + Attribute* positions; + Attribute* normals; + Attribute* uvs; + const uint32_t* indices; + size_t num_indices; + std::vector* new_vertices; + }; + + MeshData meshData{}; + meshData.positions = &positions; + meshData.normals = &normals; + meshData.uvs = &uv0s; + meshData.indices = indices.data(); + meshData.num_indices = num_indices; + meshData.new_vertices = &vertices; + vertices.resize(num_indices); + + SMikkTSpaceInterface mts_interface{}; + mts_interface.m_getNumFaces = [](const SMikkTSpaceContext* pContext) -> int { + const MeshData* meshData = static_cast(pContext->m_pUserData); + assert(meshData->num_indices % 3 == 0); + return meshData->num_indices / 3; + }; + mts_interface.m_getNumVerticesOfFace = [](const SMikkTSpaceContext*, const int) -> int { return 3; }; + mts_interface.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) -> void { + const MeshData* const meshData = static_cast(pContext->m_pUserData); + const size_t i = iFace * 3 + iVert; + assert(i < meshData->num_indices); + const size_t vertex_index = meshData->indices[i]; + const glm::vec3 pos = meshData->positions->operator[](vertex_index); + fvPosOut[0] = pos.x; + fvPosOut[1] = pos.y; + fvPosOut[2] = pos.z; + }; + mts_interface.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) -> void { + const MeshData* const meshData = static_cast(pContext->m_pUserData); + const size_t i = iFace * 3 + iVert; + assert(i < meshData->num_indices); + const size_t vertex_index = meshData->indices[i]; + const glm::vec3 norm = meshData->normals->operator[](vertex_index); + fvNormOut[0] = norm.x; + fvNormOut[1] = norm.y; + fvNormOut[2] = norm.z; + }; + mts_interface.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) -> void { + const MeshData* const meshData = static_cast(pContext->m_pUserData); + const size_t i = iFace * 3 + iVert; + assert(i < meshData->num_indices); + const size_t vertex_index = meshData->indices[i]; + const glm::vec2 uv = meshData->uvs->operator[](vertex_index); + fvTexcOut[0] = uv.x; + fvTexcOut[1] = uv.y; + }; + mts_interface.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, + const int iVert) -> void { + MeshData* const meshData = static_cast(pContext->m_pUserData); + const size_t i = iFace * 3 + iVert; + assert(i < meshData->num_indices); + const size_t vertex_index = meshData->indices[i]; + + Vertex& new_v = meshData->new_vertices->operator[](i); + + new_v.pos = meshData->positions->operator[](vertex_index); + new_v.norm = meshData->normals->operator[](vertex_index); + new_v.uv = meshData->uvs->operator[](vertex_index); + new_v.tangent.x = fvTangent[0]; + new_v.tangent.y = fvTangent[1]; + new_v.tangent.z = fvTangent[2]; + new_v.tangent.w = fSign; + }; + SMikkTSpaceContext mts_context{}; + mts_context.m_pInterface = &mts_interface; + mts_context.m_pUserData = &meshData; + + bool tan_result = genTangSpaceDefault(&mts_context); + if (tan_result == false) throw std::runtime_error("Failed to generate tangents!"); + + // regenerate indices as simple ones + indices.clear(); + indices.reserve(meshData.new_vertices->size()); + // temp generate simple indices + for (uint32_t i = 0; i < meshData.new_vertices->size(); ++i) { + indices.push_back(i); + } + } + else { + // combine vertices into one array + vertices.clear(); + vertices.reserve(num_vertices); + for (size_t i = 0; i < num_vertices; ++i) { + Vertex v{.pos = positions[i], .norm = normals[i], .tangent = tangents[i], .uv = uv0s[i]}; + vertices.push_back(v); + } } // generate mesh on GPU @@ -355,9 +468,12 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic) } } - // glTF uses the Y-up convention so objects must be rotated to Z-up - const Entity parent = - scene.CreateEntity("test_node", 0, glm::vec3{}, glm::quat{glm::one_over_root_two(), glm::one_over_root_two(), 0.0f, 0.0f}); + /* now create the entities and traverse the glTF scene hierarchy */ + const std::filesystem::path filePath(path); + const std::string name = filePath.stem().string(); + + // glTF uses the Y-up convention so the parent object must be rotated to Z-up + const Entity parent = scene.CreateEntity(name, 0, glm::vec3{}, glm::quat{glm::one_over_root_two(), glm::one_over_root_two(), 0.0f, 0.0f}); std::vector entities(model.nodes.size(), 0); std::function generateEntities = [&](Entity parent_entity, const tg::Node& node) -> void { diff --git a/test/res/models/walls_with_tangents.glb b/test/res/models/walls_with_tangents.glb index 04370905995a033039257bd4068576e23298607e..91cc84fb426eac1cfafa6d17da6fcc7dbd269b4e 100644 GIT binary patch delta 9670 zcmZvhd0bE1_x~G=rMXN|$ykKyT^ind?Mf)5gi1w8sF0yjlFnO(WLAiTT(c4~MZM1{ zE}5>&O}J*66_QXyzje;>KA-!2Jbr&X_j&JgPJ8dyUT3ep_Nq23yZy5J+3j^_%o;yj zLrqPs)%)J+e;OUvEpBHzz;gVsprO9L{+?ljEnS9S)qTu}VPnQyx;SNBYB$lzd4S~@ zUw(UvZ@ga7Z#wzmIy+tzOJ0L$pu$mprl;_y}b6He_5G_#gzTV$=!vBm8Ph8O{ z(a6fvHOSJ_Z=JPW-zMv^u0b1HXFGc*+pMQpy`pcdY47Cl`?ravoy;lglWzYmc8-H_ zz!3}Mr}<8w9ycu>8*{dkIob9lW4l>)UUItV29fmmCJ1(BI*rM0J zz12Ou$8g)X_g0^%v9!)8z0OD-(LgkjR!D244bm2AhqOnu5N)IbqJ!undWb$^fEXft zTgHe9(h=!|bVj-$T@h2H8`2#yL(CBiqz7V&^hA0gy^%ghU!)&mg;*o~kpYMeG7uSr z3`T4bJH#H5Ar6QmG6Zo#oDmnq6_FzZ0fZuMh&$qe3`IPVVaRY~1mcBwBO{Sf$Y{g| z8H4yDe#ltF9~p;?M6S<{)#CdB}Vu4v9w+kOfF0l7uWol95G73bGhUMHobZEJ4zcrN}a5IkEyt zM^+*k$SPztvIbd;tV7l#8<34iCX$70LN+5?kZfctvJJ^Wwj;U74rC{?3&}%vBYz-! zkiE!0WIu8MIfxuW4kP(U0dfQ>M2;fIkmE=ZasoMtoI*|`XOLp#EOHJhK}r!N!Xg|} zhLj`ckqgM5$VKE5Qh{7Xt{_*DYshuvFXRUDH*yoXh5Un5BDaw$ z=*bto)H(DK>aA8Wi3e{voo%L+zs5B&bZr|2@bz_gE)iBe?4x$IzEq zgQ2@?EZus#Cn(|*=<11{pl&vo_G__+V4EbGRUH7)dh_Ya2v6vzxrln4i-KFtan#;t z0yyU{rn{CU!;$9+^icM6NNHy1rFE^z0ytALyzh`fz$O&?OTF zLB&d-HJ3+0y%K2ht4Q!~1e&eB2v`?NgVv{m=?Y3mS!@KYTa<9Vg8oQrI$WMB-}~I0%I#xas@|K^%#Pg&y=zX_vhl=( zGp8BF1*B}JIo&h=6^UAEPTh+P!6eC?rn=jKP6EC+(H9KonA51LDEK4BoHG48GO%*4 zIj!H40r%3(sk31g^qSHX#~@KQN{XvlytqYfSgu%7C5E zjOn`JSpXl585(gmTb}-0izZ(g<2>}G7QMK^lg~XDffk)(?gx5PwCI+d(YU;{=%hOgeTKCY3`4XKIAnqG*Y7%qKu$e z1Ml~=hjTAl;MyoZs4Z%N$n()qplE@Fj|?>c?2^9ZSRxC4Xz-jIUMcObCR2u`-X1NC$4q5e%31kCpXCb_5z zx|c`8m<3f3cA0@+qpRTH-x=_ayb9X)%>tQS6@2ZsLvHq~41yn9yCheZf#(-9@~US! zq_iZG`oZO}?t39wU{wy)1Ktv2^K$6Y#~4m`ErM}twqzsJq?2$(n=ELlEXI$!M=0lFJB}sap4>x@lk*y{L zaA)Z;vd+2y`Yn7%Vq6R0`3_@<99;mN9@|6I&;t0P@PiZhi2Ui9 z4GxjDWI#$bgpM?U`or0<%RvTyMcL48xgY2+%Z3fIXgDv=hPqR!klVZkl5{hm>y0ho z=$Hu&yS707NLGIDlL9VX+vIw1q5_y5gUJ0=OQ5*TGSa~?4MLcqr%7-|8o2cTNK(G0 zK{4qFn|zi+hkO|vi(U$LX?~CfOMzUAg4hpf(E0mf*t9bZ=C5A~T|?7gXzoVP@014S z)pz9Gx&*?3XJ1?o`cD9leXgYJWf1Jl&mdbj1;Y{75|Z0H6y|sPOg3aq0{=CgpfP_k zFez>h(9R?bT4Ma*x^gni?iB@3nkfjTryI#VbY_djohQvkGMKupk#rd82pvXsfs}VcAg0a%6zNV7 z(aR5V&75F{$qXp%F@%BFPK#jtPX{<$u>#&al!4x|^>FZ@Jy^-Qkn2tA@Wn1izF}Z9 zc{6SXkw0qD5ME#a4u_MVK|>!7*)NB^e!8&a%vvyB%5;EFI_|`4=P@#K(0jQeb{|>gv4W^o zl#l_#3(3k$mq>iq`^0bREmEx48q^NnC*FZ(aIoqrada30ZriI#L#Hv2m->`EnHK?N zE)U7Kqw(P9e3yKbI9#^ zu~0WZlVl~Qg2l#FWSna{%w3g6+7|91iUlTem+ni5n%fkohl?)~wI{pegWO&bx3k~n z*3&g%?)QFVjh-bEX{vBT`P>*gR#Wr$UM$o8IZPpIeqsYa`k4#B6XqbdKq&kIfZ zYua5X>C2xa6m;R+OEAT*N_inNMyP*Y_Zk0AO)b%8icqiXc$qyIc$jS|3K8nnZ%x<$ z-6O=yFGZ*`-UIcx)wB9?T2UIpjj{JlxegkmI9=bP!U*MK)H&y2L%5TdzY2;9Pp7fv zSD&#qL&YgA3&|sUdO9n8K8rJG+wM9%(>?)BdJ{Q*fS%Fjcsw$vH@bWh{(e)s1HCj` zMlVDj=G$lJV3hLN+>oxE`cqK6A+HgP=?X|no*)cphrx2l+17=O}L6t z-*7;Tf)4L}itSofA}MmdGmIcg&uE6@6{yX52CnLB!Jr~osDF7dgsw|ar>c*x`OsJz zbk&gV%0D7>U{K*gkNefY(_D370KR5lp#58_un4C}As0MMZO#L~>`>zG791G)jkY&$KJqE^)jf z1@#{IgzfH>E(z*%=9auB&Ov$OuqbH#`7aPsDF>I#5RT#hz>D*tzHTQ#=`Y&&enAY~ zCBF`;Z@_c)Xu9gyZn*eM{6BXnxLfbdNM+@QOPY{EDShjTNB$hY^(Cm zuQ(%VoqV_4ob>fg!epI*21)(&xNfPy3XztTt6pbj$Jw+rG(yboy6(jw?)2ezgb5 zye0|=vkKwjdvzjze-qoo``n{bt%#~a6vxe9wN9=Qv^7?PYxsG)#D@93jQ9o%M?5RN z@={dvAy|Vd{W~h7EX8FOSQ|$Dy}K)`gG5Dd&oI=s-2kPkgPe9D)FpG2lJ^h%3@|^w zgWKLP$ppMlxGS5Z%-$dl_{X&mtW6JdV9IJmMYGyBxz4D1Eyn=}4UD-pmJ2z~z@%Sd zgMG#&aLa2pLQ1{3jOK;~axz6Cs1%)E*33Q}t_do?@VfhflAOfc(wFt3pyw5h@M5VM zi>47wWcf3IZhW7@NH&f?l|ZdR*R!e)VjhpBhQF}UQd@fTAk(br(ln2&|&v*Uh!a3i03GZ695(KVX9?UJKOlzv@ z5dAi%ed?8@=tFQdyHB}9Qsfc-vLvl~L@6eF1O>hNJ%$5sRuqEif`3?m|&Uab^K9>|l&zTEp z)q#>ClQpYg`t${oprPGnLX6KiNzi_+HZW{Ny(Eayy4%wgmx_x@QLpS4R~q<3QgqYv zo-6M>RL{|7@}46@Bt@q`FBW`;>MOtW&_RC4C|nYRgLm$opg~n8zz_`0Becg0VkrLt z?+#Tj{BA%}^t%H|(eD9Bihd7RQuKSk3e|x58AHXAAoQZH$Zr$k{$KSvhMyuy(f3qg z3MCuaO%SG7QlwETm_Rbo)$!%LiTD{5O!TN%8}`2G|4g)CUI;tGbD|{Z*R(`-VNjAN zh~NKxj|v}&q-brn@KH&MaJ2kKB`u?kddYxMkfexzwtxGdk_m5Zd*M79)# zN`gjqsD^GS?t&nOpQeEu6fmy!b4gLb>IWsgvKh3ysAx%_GFUO*9FyIvSk_VgNOE*cj9iXp;{A@e?$>4)!tOgKB}FF| z)#Ey@mzGi2v0W(!rjnv!GY7i+j!aTS9n2{23013T>*!N(d25Lz=s)cVCfbl!%+`)A z##O|KzI*m-Qx5lcNs*h8EjRaulccCiTqo|(UNcG2^-1|`gnqH4X#aLkIl}J^l%LTR zS8l_8%zCO^_pW@K((1RHCD+aA$}ysP21(5C&7fauC^f2AmlRoDbED(qUw}%{KWdL* zuyqEgHk-S$k0pnU{NyUv-8-S0?Uu3x6^VjkWo}$r+$(8!wcQrX6`Qq|1XaCu;f`*4 z$ucS%{r#7eEd7EtYoIf+LL(>1xh^Dj>k{x#Z=P-TV{@HoCR3nGId9At_ot zD-aJM3nWDz;R)Qu^&9^iFK`cOU(6@%SBWq1AyvJ*FHwb57!6Tf-$7DL$A@I-?};iT<3lz)sF3@nq6zr+ zen(V-Al}KL*<4j7;$y>PC|rsIRk(s(1KDyZaxP(B9S`$SZP?JI1G zy7N)6pol*~{pn$&EE*_2|9Itsyr%jzv3r#&Jb%3=h#pQeVD)mvkd6i}qD+>HyA*cg z$fyVOV^v{uw-j~Se$_6eDy+u6LjJs>GjDT2(fxw&EPeyhGOI0{$ZdTzPO|aPBMWg= zg-c<#$KL_m`WJSfn$f9D6T?1t%pv~8;)p9tr1&-6B?Xu=)A*3+z#svjwX| z1OW{{ncMP;b4~<16mFE&KE?z@x}=C~ABHBV1l7^XX+|V>O!Kv*$e0f2n3z&f9nH2B z)w24@j-Wcq@#fLUS*cVVm0G2N&Fs-m&Ah zh=)ghS-snA$f*vOBQ%|;g}XZEdsNJL>{C92A;k zK@GF|a5MXNq~hrp&k5zuL%B9fdSli?jO*JK4B*nL+ft(`;zx4x#J}u;h3W7$TQouL zAA6KMnW5rG<=5N@tA8$MC(Ra*>q*JWp`cq==wU7%*VC%|(%p>)-0T4Hcprbtfxeckup1|#I*U3Id^7zOeBKOQ7;H);e`mI^;8 zi~&dECL-F{>iv5*DK`Sodtw$$Bj*kK*L689yeDSOxW!6#LiuHwnIop%{ta8eW_4bs z-1$*VyJdB5h4#M7F4Li?SV8~(_8BuRY6>@_DU{)F;0Hz*-?Zl@t`L(>mu4H&ybM21 zm8Iex(7HBmTn}?GtCiEP1mf=2VOJ4K?hIqX*T*MMqFk-pVzS( z{R3%9v6z-SyY>=0`}IsdE9M|f86WrmadHG*o>GSmDd@|34(;07I{kS^xk5 delta 1360 zcmW;MXF$wx7{KxFPPxNfuDXV(>vCq9(J-?276~DQjF3Gd%F6bS?7ep~GS4P^kBnrG z?7e*-FFxPj^Xhr`{F1U#b-7Ba&d{@OSUt6!on3CGRW;g}X2{SgIob%1KtD^f=B=96 zY+?xsiubd`#CDJA7Cp!k5}Y2V+pJN#80?i*`lU*!-kaH?jMbacJsj7mm1HNAa?Mzl z*Hv9UNNH*GSHhiLGy#w> zE3`%!+Mq4M(GC%4j}GXFNOVGHbU_rlq8qv+8a>bxy%2-m=!3rKhgkH-01QMN24OIU zU?_%RI7VP3MqxDKF$QCifN>a)L?mGXCSnpMV+xWn71J;sGcXggFdK8AAO&+V52=`s z1z3nhSd1lDie*@i69M0ncF5(g{;|i|g8m{98ZsHbhBMWzM7x!=< z*?52)Jj5eB#uGfnGd#x&yu>Ty;x*pjE#BchKHwuh;WNJAE56}7e&8p5;Wz%^?^JGo zCM0T!Mv_NjFL99Mm1re8Nj^z_NdbvoVvsmW3QCL;C&~ZyE;5-Ut`awiyTn6MNa86e oEGZ)Kl6XtZ5+8|0;wvetvhhc#x=ypDthB0zd)bn*t*Qk5KhrT@a{vGU diff --git a/test/src/game.cpp b/test/src/game.cpp index 6cf242c..8c72159 100644 --- a/test/src/game.cpp +++ b/test/src/game.cpp @@ -50,7 +50,7 @@ void PlayGame(GameSettings settings) graphics_settings.vsync = true; graphics_settings.wait_for_present = false; graphics_settings.msaa_level = engine::gfx::MSAALevel::kOff; - graphics_settings.enable_anisotropy = false; + graphics_settings.enable_anisotropy = true; engine::Application::Configuration configuration{}; configuration.enable_frame_limiter = settings.enable_frame_limiter; @@ -167,15 +167,16 @@ void PlayGame(GameSettings settings) scene2->AddComponent(camera); } - { /* axes */ - //engine::util::LoadMeshFromFile(scene2, app.GetResourcePath("models/MY_AXES.dae"), true); + { + /* axes */ + // engine::util::LoadMeshFromFile(scene2, app.GetResourcePath("models/MY_AXES.dae"), true); } { /* floor */ - engine::Entity pivot = scene2->CreateEntity("pivot", 0, glm::vec3{ 0.0f, 0.0f, 0.0f }); + engine::Entity pivot = scene2->CreateEntity("pivot", 0, glm::vec3{0.0f, 0.0f, 0.0f}); - engine::Entity wall2 = scene2->CreateEntity("wall2", pivot, glm::vec3{-50.0f, -50.0f, 0.0f}); + engine::Entity wall2 = scene2->CreateEntity("floor", pivot, glm::vec3{-50.0f, -50.0f, 0.0f}); auto wall_renderable = scene2->AddComponent(wall2); wall_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(), 100.0f, 100.0f, 0.1f, 100.0f); wall_renderable->material = std::make_unique(app.renderer(), app.GetResource("builtin.fancy")); @@ -197,14 +198,19 @@ void PlayGame(GameSettings settings) wall_renderable->material->SetAlbedoTexture(app.GetResource("builtin.white")); } - auto teapot = engine::util::LoadGLTF(*scene2, app.GetResourcePath("models/teapot_with_tangents.glb")); - scene2->GetComponent(teapot)->scale *= 10.0f; - //auto teapot2 = engine::util::LoadGLTF(*scene2, app.GetResourcePath("models/teapot.glb")); - //scene2->GetComponent(teapot2)->scale *= 10.0f; - //scene2->GetComponent(teapot2)->position.y += 5.0f; - //scene2->GetComponent(teapot2)->rotation = glm::angleAxis(glm::pi(), glm::vec3{ 0.0f, 0.0f, 1.0f }); - //scene2->GetComponent(teapot2)->rotation *= glm::angleAxis(glm::half_pi(), glm::vec3{1.0f, 0.0f, 0.0f}); - auto walls = engine::util::LoadGLTF(*scene2, app.GetResourcePath("models/walls_with_tangents.glb")); + //auto teapot = engine::util::LoadGLTF(*scene2, app.GetResourcePath("models/teapot_with_tangents.glb")); + //scene2->GetComponent(teapot)->scale *= 10.0f; + auto teapot2 = engine::util::LoadGLTF(*scene2, app.GetResourcePath("models/teapot.glb")); + scene2->GetComponent(teapot2)->scale *= 10.0f; + scene2->GetComponent(teapot2)->position.y += 5.0f; + auto custom = scene2->AddComponent(teapot2); + custom->onInit = [](void) { return; }; + custom->onUpdate = [&](float dt) { + scene2->GetComponent(teapot2)->rotation *= glm::angleAxis(dt, glm::vec3{0.0f, 1.0f, 0.0f}); + }; + // scene2->GetComponent(teapot2)->rotation = glm::angleAxis(glm::pi(), glm::vec3{ 0.0f, 0.0f, 1.0f }); + // scene2->GetComponent(teapot2)->rotation *= glm::angleAxis(glm::half_pi(), glm::vec3{1.0f, 0.0f, 0.0f}); + // auto walls = engine::util::LoadGLTF(*scene2, app.GetResourcePath("models/walls_with_tangents.glb")); } my_scene->GetSystem()->next_scene_ = scene2;