-
Posts
24,628 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Downloads
Everything posted by Josh
-
Update is available now which I believe fixes this. I tested on the standalone.
-
Okay, building from the engine source works, but from the lib does not. It probably is interfering with assimp...let me do another build without it. (I only updated the editor last time.)
-
What example is not working in this example? When I run it, it loads the folder and finds a file called "è¿a¿½½¿µá.txt" in the RU folder.
-
I guess just go without whatever format is in use. The fact that nobody understand or even knows what BC7 is probably means it isn't that important in the grand scheme of things. If someone wants BC7, we can do an auto-converter in the editor from an image file. It would be better to have something simple and reliable that works now than to have something that produces perfect results but breaks easily.
-
Yeah, but if we got a static exporter set up, that would cover 95% of use cases.
-
I thought you had a working exporter your wrote yourself?
-
-
Yes
-
How hard would it be to export to this format from Blender?
-
I am considering implementing our own file format and using a pipeline more like Leadwerks, where glTF and FBX models get automatically converted by the editor. You can still use glTF files for your final game files if you wish, and the converter can be disabled in the program settings if you wish. The file format is designed to be very simple to read and write, while loading fast enough for game use. Features: LODs Skeletal animation External material files Vertex morphs User-defined entity properties Embedded collider Embedded picking structure I think it is easiest to understand the file format just by looking at the loading code: #include "UltraEngine.h" using namespace UltraEngine; namespace UltraEngine::Core { String G3DModelLoader::ReadText(shared_ptr<Stream> stream) { int len = stream->ReadInt(); auto pos = stream->GetPosition(); String s; if (len) { s = stream->ReadString(len); stream->Seek(pos + len); } return s; } bool G3DModelLoader::Reload(shared_ptr<Stream> stream, shared_ptr<Object> o, const LoadFlags flags) { auto modelbase = o->As<ModelBase>(); if (modelbase == NULL) return false; modelbase->model = CreateModel(NULL); auto model = modelbase->model->As<Model>(); if (stream->ReadString(4) != "G3D") return false; int version = stream->ReadInt(); if (version != 100) { Print("Error: G3D version " + String(version) + " not supported"); return false; } return LoadNode(stream, model, flags); } bool G3DModelLoader::LoadNode(shared_ptr<Stream> stream, shared_ptr<Model> model, const LoadFlags flags) { Vec3 pos, scale; Quat rot; String s; if (stream->ReadString(4) != "NODE") return false; model->name = ReadText(stream); model->properties = ParseJson(ReadText(stream)); ParseJson(ReadText(stream)); pos.x = stream->ReadFloat(); pos.y = stream->ReadFloat(); pos.z = stream->ReadFloat(); rot.x = stream->ReadFloat(); rot.y = stream->ReadFloat(); rot.z = stream->ReadFloat(); rot.w = stream->ReadFloat(); scale.x = stream->ReadFloat(); scale.y = stream->ReadFloat(); scale.z = stream->ReadFloat(); model->SetPosition(pos); model->SetRotation(rot); model->SetScale(scale); int countlods = stream->ReadInt(); for (int level = 0; level < countlods; ++level) { if (not LoadLod(stream, model, level, flags)) return false; } int countkids = stream->ReadInt(); for (int n = 0; n < countkids; ++n) { auto child = CreateModel(NULL); child->SetParent(model); if (not LoadNode(stream, child, flags)) return false; } // Animations int animcount = stream->ReadInt(); for (int n = 0; n < animcount; ++n) { stream->ReadInt();// length stream->ReadFloat();// speed auto name = ReadText(stream); } // Skeleton int bones = stream->ReadInt(); if (bones) { if (model->GetParent()) { Print("Error: Skeleton can only appear in the model root node"); return false; } if (bones != 1) { Print("Error: Skeleton root must have one bone"); return false; } auto skeleton = CreateSkeleton(nullptr); model->SetSkeleton(skeleton); for (int n = 0; n < bones; ++n) { auto bone = std::make_shared<Bone>(nullptr, skeleton); LoadBone(stream, skeleton, bone, animcount, flags); } skeleton->UpdateSkinning(); model->SetSkeleton(skeleton); } // Collider int partscount = stream->ReadInt(); model->UpdateBounds(); return true; } bool G3DModelLoader::LoadLod(shared_ptr<Stream> stream, shared_ptr<Model> model, const int level, const LoadFlags flags) { if (stream->ReadString(4) != "LOD ") return false; if (level >= model->lods.size()) model->AddLod(); float loddistance = stream->ReadFloat(); int countmeshes = stream->ReadInt(); for (int m = 0; m < countmeshes; ++m) { if (not LoadMesh(stream, model, level, flags)) return false; } return true; } bool G3DModelLoader::LoadMesh(shared_ptr<Stream> stream, shared_ptr<Model> model, const int level, const LoadFlags flags) { if (stream->ReadString(4) != "MESH") return false; MeshPrimitives type = MeshPrimitives(stream->ReadInt()); if (type < 1 or type > 4) { Print("Error: Mesh type must be between one and four"); return false; } auto mesh = model->AddMesh(type, level); mesh->name = ReadText(stream); WString mtlpath = ReadText(stream); if (not mtlpath.empty()) { if (mtlpath.Left(2) == "./" and not stream->path.empty()) { mtlpath = ExtractDir(stream->path) + "/" + mtlpath; } auto mtl = LoadMaterial(mtlpath); if (mtl) mesh->SetMaterial(mtl); } int vertexstride = stream->ReadInt(); if (vertexstride != 84) return false; int vertexcount = stream->ReadInt(); mesh->m_vertices.resize(vertexcount); for (int v = 0; v < vertexcount; ++v) { mesh->m_vertices[v].position.x = stream->ReadFloat(); mesh->m_vertices[v].position.y = stream->ReadFloat(); mesh->m_vertices[v].position.z = stream->ReadFloat(); mesh->m_vertices[v].normal.x = stream->ReadFloat(); mesh->m_vertices[v].normal.y = stream->ReadFloat(); mesh->m_vertices[v].normal.z = stream->ReadFloat(); mesh->m_vertices[v].texcoords.x = stream->ReadFloat(); mesh->m_vertices[v].texcoords.y = stream->ReadFloat(); mesh->m_vertices[v].texcoords.z = stream->ReadFloat(); mesh->m_vertices[v].texcoords.w = stream->ReadFloat(); mesh->m_vertices[v].color.r = float(stream->ReadByte()) / 255.0f; mesh->m_vertices[v].color.g = float(stream->ReadByte()) / 255.0f; mesh->m_vertices[v].color.b = float(stream->ReadByte()) / 255.0f; mesh->m_vertices[v].color.a = float(stream->ReadByte()) / 255.0f; mesh->m_vertices[v].displacement = stream->ReadFloat(); mesh->m_vertices[v].tangent.x = stream->ReadFloat(); mesh->m_vertices[v].tangent.y = stream->ReadFloat(); mesh->m_vertices[v].tangent.z = stream->ReadFloat(); mesh->m_vertices[v].bitangent.x = stream->ReadFloat(); mesh->m_vertices[v].bitangent.y = stream->ReadFloat(); mesh->m_vertices[v].bitangent.z = stream->ReadFloat(); mesh->m_vertices[v].boneindices[0] = stream->ReadShort(); mesh->m_vertices[v].boneindices[1] = stream->ReadShort(); mesh->m_vertices[v].boneindices[2] = stream->ReadShort(); mesh->m_vertices[v].boneindices[3] = stream->ReadShort(); mesh->m_vertices[v].boneweights.x = float(stream->ReadByte()) / 255.0f; mesh->m_vertices[v].boneweights.y = float(stream->ReadByte()) / 255.0f; mesh->m_vertices[v].boneweights.z = float(stream->ReadByte()) / 255.0f; mesh->m_vertices[v].boneweights.w = float(stream->ReadByte()) / 255.0f; } int indicesize = stream->ReadInt(); int indicecount = stream->ReadInt(); uint32_t index; switch (indicesize) { case 2: mesh->m_indices.reserve(indicecount); for (int i = 0; i < indicecount; ++i) mesh->AddIndice(stream->ReadShort()); break; case 4: mesh->m_indices.resize(indicecount); stream->Read(mesh->m_indices.data(), indicecount * sizeof(mesh->indices[0])); break; default: return false; } // Pick structure cache int pickcachesize = stream->ReadInt(); if (pickcachesize) stream->Seek(stream->GetPosition() + pickcachesize); //Vertex morphs int morphcount = stream->ReadInt(); for (int m = 0; m < morphcount; ++m) { if (stream->ReadString(4) != "MORP") return false; if (stream->ReadInt() != 48) return false; for (int v = 0; v < vertexcount; ++v) { // Position stream->ReadFloat(); stream->ReadFloat(); stream->ReadFloat(); // Normal stream->ReadFloat(); stream->ReadFloat(); stream->ReadFloat(); // Tangent stream->ReadFloat(); stream->ReadFloat(); stream->ReadFloat(); // Bitangent stream->ReadFloat(); stream->ReadFloat(); stream->ReadFloat(); } } mesh->UpdateBounds(); return true; } bool G3DModelLoader::LoadBone(shared_ptr<Stream> stream, shared_ptr<Skeleton> skeleton, shared_ptr<Bone> bone, const int animcount, const LoadFlags flags) { bone->name = ReadText(stream); bone->position.x = stream->ReadFloat(); bone->position.y = stream->ReadFloat(); bone->position.z = stream->ReadFloat(); bone->quaternion.x = stream->ReadFloat(); bone->quaternion.y = stream->ReadFloat(); bone->quaternion.z = stream->ReadFloat(); bone->quaternion.w = stream->ReadFloat(); bone->scale = stream->ReadFloat(); stream->ReadFloat();// scale y stream->ReadFloat();// scale z int count = stream->ReadInt(); if (count != animcount) { Print("Error: Bone animation count must match that of the root node"); return false; } for (int anim = 0; anim < count; ++anim) { if (stream->ReadString(4) != "ANIM") return false; int keyflags = stream->ReadInt(); int keyframes = stream->ReadInt(); if (keyflags) { for (int k = 0; k < keyframes; ++k) { if ((1 & keyflags) != 0) { stream->ReadFloat(); stream->ReadFloat(); stream->ReadFloat(); } if ((2 & keyflags) != 0) { stream->ReadFloat(); stream->ReadFloat(); stream->ReadFloat(); stream->ReadFloat(); } if ((4 & keyflags) != 0) { stream->ReadFloat(); stream->ReadFloat(); stream->ReadFloat(); } } } } return true; } }
-
Seems to cause problems of its own. According to this, the Godot developers gave up and implemented their own FBX converter: https://github.com/assimp/assimp/issues/2498
-
This might be the solution, maybe: https://github.com/assimp/assimp/issues/4035#issuecomment-1497239561
-
Multiple instances still running after crash to desktop.
Josh replied to CJO Games's topic in Bug Reports
A bug was fixed that would cause launched processes to hang. This may resolve your issue with the preview tool. -
0.9.5 Removed assimp library due to this issue. Removed FBX to glTF converter script. Removed Collada to glTF converter script. Added FBX to MDL converter tool and script. Fixed bug that would cause launched processes to hang forever. This could affect both your launched games, converters, and possibly the preview tool.
-
Reported here: https://github.com/assimp/assimp/issues/5534 I am not going to continue on this path.
-
-
It looks like there is a very bad problem with bones in assimp. It looks like it quadruples the number of bones in the model.
-
It is possible that maybe assimp and my libzip are conflicting somehow?
-
0.9.5 Some bug fixes Added experimental support for FBX and X files. Animation is not yet supported. You must add this header search path to existing C++ projects in the project settings: $(ULTRAENGINE)\Include\Libraries\assimp\include You will also see noticeably smoother camera movement, best with release mode and VSync on.
-
Okay, this was just because of the change in the scene tree...should be working in next build.
- 1 reply
-
- 1
-
Okay, I believe this will be fixed when a new build goes up...
-
-
I correct the function definition: "Point", sol::overload ( [](Entity& e, shared_ptr<Entity> target) { e.Point(target); }, [](Entity& e, shared_ptr<Entity> target, int a) { e.Point(target, a); }, [](Entity& e, shared_ptr<Entity> target, int a, float r) { e.Point(target, a, r); }, [](Entity& e, shared_ptr<Entity> target, int a, float r, float z) { e.Point(target, a, r, z); }, [](Entity& e, Vec3& target) { e.Point(target); }, [](Entity& e, Vec3& target, int a) { e.Point(target, a); }, [](Entity& e, Vec3& target, int a, float r) { e.Point(target, a, r); }, [](Entity& e, Vec3& target, int a, float r, float z) { e.Point(target, a, r, z); }, [](Entity& e, float x, float y, float z) { e.Point(x,y,z); }, [](Entity& e, float x, float y, float z, int a) { e.Point(x, y, z, a); }, [](Entity& e, float x, float y, float z, int a, float r) { e.Point(x, y, z, a, r); }, [](Entity& e, float x, float y, float z, int a, float r, float roll) { e.Point(x, y, z, a, r, roll); } ),
-
Test: local world = CreateWorld() local box = CreateBox(world) local box2 = CreateBox(world); box:SetPosition(2,0,0) box:Point(box2, 2, 1, 0) result: sol: no matching function call takes this number of arguments and the specified types