From b2a450a3087fb8393024876f6069a7cec9855bfd Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 9 Apr 2024 19:21:10 -0500 Subject: #1126 gltf scene import prototype (#1172) * #1126 GLTF Scene import initial prototype (working geometry import for some assets) * #1126 WIP -- Expand support for more vertex formats, PoC material import, shadow support, scale support * #1126 move GLTF implementation to newview/gltf * #1126 Refactor attribute loading to be less copy/pasta for each combination of types * #1126 Partially working object selection. Ability to have multiple scenes at once. Helpful message on how to use the preview button. * #1126 Add bounding box debug display and untangle GLTF raycast from LLVOVolume raycast * #1126 Working raycast on GLTF scenes. * #1126 Remove some #pragma optimize offs --- indra/newview/gltfscenemanager.cpp | 469 +++++++++++++++++++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 indra/newview/gltfscenemanager.cpp (limited to 'indra/newview/gltfscenemanager.cpp') diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp new file mode 100644 index 0000000000..429c9118f8 --- /dev/null +++ b/indra/newview/gltfscenemanager.cpp @@ -0,0 +1,469 @@ +/** + * @file gltfscenemanager.cpp + * @brief Builds menus out of items. + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "gltfscenemanager.h" +#include "llviewermenufile.h" +#include "llappviewer.h" +#include "lltinygltfhelper.h" +#include "llvertexbuffer.h" +#include "llselectmgr.h" +#include "llagent.h" +#include "llnotificationsutil.h" +#include "llvoavatarself.h" +#include "llvolumeoctree.h" +#include "gltf/asset.h" +#include "pipeline.h" +#include "llviewershadermgr.h" + + +using namespace LL; + +// temporary location of LL GLTF Implementation +using namespace LL::GLTF; + +void GLTFSceneManager::load() +{ + LLViewerObject* obj = LLSelectMgr::instance().getSelection()->getFirstRootObject(); + + if (obj) + { + // Load a scene from disk + LLFilePickerReplyThread::startPicker( + [](const std::vector& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter) + { + if (LLAppViewer::instance()->quitRequested()) + { + return; + } + if (filenames.size() > 0) + { + GLTFSceneManager::instance().load(filenames[0]); + } + }, + LLFilePicker::FFLOAD_GLTF, + true); + } + else + { + LLNotificationsUtil::add("GLTFPreviewSelection"); + } +} + +void GLTFSceneManager::load(const std::string& filename) +{ + tinygltf::Model model; + LLTinyGLTFHelper::loadModel(filename, model); + + LLPointer asset = new Asset(); + *asset = model; + + asset->allocateGLResources(filename, model); + asset->updateTransforms(); + + // hang the asset off the currently selected object, or off of the avatar if no object is selected + LLViewerObject* obj = LLSelectMgr::instance().getSelection()->getFirstRootObject(); + + if (obj) + { // assign to self avatar + obj->mGLTFAsset = asset; + mObjects.push_back(obj); + } +} + +GLTFSceneManager::~GLTFSceneManager() +{ + mObjects.clear(); +} + +LLMatrix4a getAssetToAgentTransform(LLViewerObject* obj) +{ + LLMatrix4 root; + root.initScale(obj->getScale()); + root.rotate(obj->getRenderRotation()); + root.translate(obj->getPositionAgent()); + + LLMatrix4a mat; + mat.loadu((F32*) root.mMatrix); + + return mat; +} + +LLMatrix4a getAgentToAssetTransform(LLViewerObject* obj) +{ + LLMatrix4 root; + LLVector3 scale = obj->getScale(); + scale.mV[0] = 1.f / scale.mV[0]; + scale.mV[1] = 1.f / scale.mV[1]; + scale.mV[2] = 1.f / scale.mV[2]; + + root.translate(-obj->getPositionAgent()); + root.rotate(~obj->getRenderRotation()); + + LLMatrix4 scale_mat; + scale_mat.initScale(scale); + + root *= scale_mat; + + + LLMatrix4a mat; + mat.loadu((F32*) root.mMatrix); + + return mat; +} + +void GLTFSceneManager::renderOpaque() +{ + // for debugging, just render the whole scene as opaque + // by traversing the whole scenegraph + // Assumes camera transform is already set and + // appropriate shader is already bound + + gGL.matrixMode(LLRender::MM_MODELVIEW); + + for (U32 i = 0; i < mObjects.size(); ++i) + { + if (mObjects[i]->isDead() || mObjects[i]->mGLTFAsset == nullptr) + { + mObjects.erase(mObjects.begin() + i); + --i; + continue; + } + + Asset* asset = mObjects[i]->mGLTFAsset; + + gGL.pushMatrix(); + + LLMatrix4a mat = getAssetToAgentTransform(mObjects[i]); + + LLMatrix4a modelview; + modelview.loadu(gGLModelView); + + matMul(mat, modelview, modelview); + + asset->updateRenderTransforms(modelview); + asset->renderOpaque(); + + gGL.popMatrix(); + } +} + +LLMatrix4a inverse(const LLMatrix4a& mat) +{ + glh::matrix4f m((F32*)mat.mMatrix); + m = m.inverse(); + LLMatrix4a ret; + ret.loadu(m.m); + return ret; +} + +bool GLTFSceneManager::lineSegmentIntersect(LLVOVolume* obj, Asset* asset, const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32* node_hit, S32* primitive_hit, + LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) + +{ + // line segment intersection test + // start and end should be in agent space + // volume space and asset space should be the same coordinate frame + // results should be transformed back to agent space + + bool ret = false; + + LLVector4a local_start; + LLVector4a local_end; + + LLMatrix4a asset_to_agent = getAssetToAgentTransform(obj); + LLMatrix4a agent_to_asset = inverse(asset_to_agent); + + agent_to_asset.affineTransform(start, local_start); + agent_to_asset.affineTransform(end, local_end); + + LLVector4a p; + LLVector4a n; + LLVector2 tc; + LLVector4a tn; + + if (intersection != NULL) + { + p = *intersection; + } + + if (tex_coord != NULL) + { + tc = *tex_coord; + } + + if (normal != NULL) + { + n = *normal; + } + + if (tangent != NULL) + { + tn = *tangent; + } + + S32 hit_node_index = asset->lineSegmentIntersect(local_start, local_end, &p, &tc, &n, &tn, primitive_hit); + + if (hit_node_index >= 0) + { + local_end = p; + if (node_hit != NULL) + { + *node_hit = hit_node_index; + } + + if (intersection != NULL) + { + asset_to_agent.affineTransform(p, *intersection); + } + + if (normal != NULL) + { + LLVector3 v_n(n.getF32ptr()); + normal->load3(obj->volumeDirectionToAgent(v_n).mV); + (*normal).normalize3fast(); + } + + if (tangent != NULL) + { + LLVector3 v_tn(tn.getF32ptr()); + + LLVector4a trans_tangent; + trans_tangent.load3(obj->volumeDirectionToAgent(v_tn).mV); + + LLVector4Logical mask; + mask.clear(); + mask.setElement<3>(); + + tangent->setSelectWithMask(mask, tn, trans_tangent); + (*tangent).normalize3fast(); + } + + if (tex_coord != NULL) + { + *tex_coord = tc; + } + + ret = true; + } + + return ret; +} + +LLDrawable* GLTFSceneManager::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, + BOOL pick_transparent, + BOOL pick_rigged, + BOOL pick_unselectable, + BOOL pick_reflection_probe, + S32* node_hit, // return the index of the node that was hit + S32* primitive_hit, // return the index of the primitive that was hit + LLVector4a* intersection, // return the intersection point + LLVector2* tex_coord, // return the texture coordinates of the intersection point + LLVector4a* normal, // return the surface normal at the intersection point + LLVector4a* tangent) // return the surface tangent at the intersection point +{ + LLDrawable* drawable = nullptr; + + LLVector4a local_end = end; + LLVector4a position; + + for (U32 i = 0; i < mObjects.size(); ++i) + { + if (mObjects[i]->isDead() || mObjects[i]->mGLTFAsset == nullptr || !mObjects[i]->getVolume()) + { + mObjects.erase(mObjects.begin() + i); + --i; + continue; + } + + // temporary debug -- always double check objects that have GLTF scenes hanging off of them even if the ray doesn't intersect the object bounds + if (lineSegmentIntersect((LLVOVolume*) mObjects[i].get(), mObjects[i]->mGLTFAsset, start, local_end, -1, pick_transparent, pick_rigged, pick_unselectable, node_hit, primitive_hit, &position, tex_coord, normal, tangent)) + { + local_end = position; + if (intersection) + { + *intersection = position; + } + drawable = mObjects[i]->mDrawable; + } + } + + return drawable; +} + +void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size); + +extern LLVector4a gDebugRaycastStart; +extern LLVector4a gDebugRaycastEnd; + +void renderOctreeRaycast(const LLVector4a& start, const LLVector4a& end, const LLVolumeOctree* octree); + +void renderAssetDebug(LLViewerObject* obj, Asset* asset) +{ + // render debug + // assumes appropriate shader is already bound + // assumes modelview matrix is already set + + gGL.pushMatrix(); + + // get raycast in asset space + LLMatrix4a asset_to_agent = getAssetToAgentTransform(obj); + LLMatrix4a agent_to_asset = getAgentToAssetTransform(obj); + + LLVector4a start; + LLVector4a end; + + agent_to_asset.affineTransform(gDebugRaycastStart, start); + agent_to_asset.affineTransform(gDebugRaycastEnd, end); + + + for (auto& node : asset->mNodes) + { + Mesh& mesh = asset->mMeshes[node.mMesh]; + + if (node.mMesh != INVALID_INDEX) + { + gGL.loadMatrix((F32*)node.mRenderMatrix.mMatrix); + + // draw bounding box of mesh primitives + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) + { + gGL.color3f(0.f, 1.f, 1.f); + + for (auto& primitive : mesh.mPrimitives) + { + auto* listener = (LLVolumeOctreeListener*) primitive.mOctree->getListener(0); + + LLVector4a center = listener->mBounds[0]; + LLVector4a size = listener->mBounds[1]; + + drawBoxOutline(center, size); + } + } + +#if 0 + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST)) + { + gGL.flush(); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + // convert raycast to node local space + LLVector4a local_start; + LLVector4a local_end; + + node.mAssetMatrixInv.affineTransform(start, local_start); + node.mAssetMatrixInv.affineTransform(end, local_end); + + for (auto& primitive : mesh.mPrimitives) + { + if (primitive.mOctree.notNull()) + { + renderOctreeRaycast(local_start, local_end, primitive.mOctree); + } + } + + gGL.flush(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } +#endif + } + } + + gGL.popMatrix(); +} + +void GLTFSceneManager::renderDebug() +{ + if (!gPipeline.hasRenderDebugMask( + LLPipeline::RENDER_DEBUG_BBOXES | + LLPipeline::RENDER_DEBUG_RAYCAST)) + { + return; + } + + gDebugProgram.bind(); + + LLGLDisable cullface(GL_CULL_FACE); + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gPipeline.disableLights(); + + for (auto& obj : mObjects) + { + if (obj->isDead() || obj->mGLTFAsset == nullptr) + { + continue; + } + + Asset* asset = obj->mGLTFAsset; + + + LLMatrix4a mat = getAssetToAgentTransform(obj); + + LLMatrix4a modelview; + modelview.loadu(gGLModelView); + + matMul(mat, modelview, modelview); + + asset->updateRenderTransforms(modelview); + renderAssetDebug(obj, asset); + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST)) + { + S32 node_hit = -1; + S32 primitive_hit = -1; + LLVector4a intersection; + + LLDrawable* drawable = lineSegmentIntersect(gDebugRaycastStart, gDebugRaycastEnd, TRUE, TRUE, TRUE, TRUE, &node_hit, &primitive_hit, &intersection, nullptr, nullptr, nullptr); + + if (drawable) + { + gGL.pushMatrix(); + Asset* asset = drawable->getVObj()->mGLTFAsset; + Node* node = &asset->mNodes[node_hit]; + Primitive* primitive = &asset->mMeshes[node->mMesh].mPrimitives[primitive_hit]; + + gGL.flush(); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + gGL.color3f(1, 0, 1); + drawBoxOutline(intersection, LLVector4a(0.1f, 0.1f, 0.1f, 0.f)); + + gGL.loadMatrix((F32*) node->mRenderMatrix.mMatrix); + + + + auto* listener = (LLVolumeOctreeListener*) primitive->mOctree->getListener(0); + drawBoxOutline(listener->mBounds[0], listener->mBounds[1]); + + gGL.flush(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + gGL.popMatrix(); + } + } + gDebugProgram.unbind(); +} + -- cgit v1.2.3 From 720f7d7ef5d06366cdbae51cd67a6883e994880b Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 10 Apr 2024 11:25:07 -0500 Subject: Fix mac build (#1182) * Fix mac build * Mac build take 2 * Mac build take 3 --- indra/newview/gltfscenemanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/gltfscenemanager.cpp') diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index 429c9118f8..6c44b83646 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "llviewerprecompiledheaders.h" + #include "gltfscenemanager.h" #include "llviewermenufile.h" #include "llappviewer.h" @@ -329,7 +331,6 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset) gGL.pushMatrix(); // get raycast in asset space - LLMatrix4a asset_to_agent = getAssetToAgentTransform(obj); LLMatrix4a agent_to_asset = getAgentToAssetTransform(obj); LLVector4a start; -- cgit v1.2.3 From bc93177ea0788a245554882b6d721eae2e057206 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 17 Apr 2024 16:12:49 -0500 Subject: 1176 integrate llgltfnode with selection manager and llmaniptranslate/rotate (#1258) * #1176 Somewhat working GLTF Node support for translate tool * #1176 Missing file from last commit * #1176 Better translation for rotated nodes. * #1176 Fix for objects snapping back to original position * #1176 GLTF Samples compatibility pass -- attempt at improving rotation manip support, incidental cleanup, GLTF node debug display * #1176 Clean out some unused and not working functions. * #1176 Fix for mac build, incidental cleanup * Mac build fix --- indra/newview/gltfscenemanager.cpp | 153 +++++++++++++++++++++++++++---------- 1 file changed, 114 insertions(+), 39 deletions(-) (limited to 'indra/newview/gltfscenemanager.cpp') diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index 6c44b83646..8273c707f9 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -91,7 +91,11 @@ void GLTFSceneManager::load(const std::string& filename) if (obj) { // assign to self avatar obj->mGLTFAsset = asset; - mObjects.push_back(obj); + + if (std::find(mObjects.begin(), mObjects.end(), obj) == mObjects.end()) + { + mObjects.push_back(obj); + } } } @@ -100,43 +104,17 @@ GLTFSceneManager::~GLTFSceneManager() mObjects.clear(); } -LLMatrix4a getAssetToAgentTransform(LLViewerObject* obj) +void GLTFSceneManager::renderOpaque() { - LLMatrix4 root; - root.initScale(obj->getScale()); - root.rotate(obj->getRenderRotation()); - root.translate(obj->getPositionAgent()); - - LLMatrix4a mat; - mat.loadu((F32*) root.mMatrix); - - return mat; + render(true); } -LLMatrix4a getAgentToAssetTransform(LLViewerObject* obj) +void GLTFSceneManager::renderAlpha() { - LLMatrix4 root; - LLVector3 scale = obj->getScale(); - scale.mV[0] = 1.f / scale.mV[0]; - scale.mV[1] = 1.f / scale.mV[1]; - scale.mV[2] = 1.f / scale.mV[2]; - - root.translate(-obj->getPositionAgent()); - root.rotate(~obj->getRenderRotation()); - - LLMatrix4 scale_mat; - scale_mat.initScale(scale); - - root *= scale_mat; - - - LLMatrix4a mat; - mat.loadu((F32*) root.mMatrix); - - return mat; + render(false); } -void GLTFSceneManager::renderOpaque() +void GLTFSceneManager::render(bool opaque) { // for debugging, just render the whole scene as opaque // by traversing the whole scenegraph @@ -158,7 +136,7 @@ void GLTFSceneManager::renderOpaque() gGL.pushMatrix(); - LLMatrix4a mat = getAssetToAgentTransform(mObjects[i]); + LLMatrix4a mat = mObjects[i]->getGLTFAssetToAgentTransform(); LLMatrix4a modelview; modelview.loadu(gGLModelView); @@ -166,7 +144,7 @@ void GLTFSceneManager::renderOpaque() matMul(mat, modelview, modelview); asset->updateRenderTransforms(modelview); - asset->renderOpaque(); + asset->render(opaque); gGL.popMatrix(); } @@ -195,7 +173,7 @@ bool GLTFSceneManager::lineSegmentIntersect(LLVOVolume* obj, Asset* asset, const LLVector4a local_start; LLVector4a local_end; - LLMatrix4a asset_to_agent = getAssetToAgentTransform(obj); + LLMatrix4a asset_to_agent = obj->getGLTFAssetToAgentTransform(); LLMatrix4a agent_to_asset = inverse(asset_to_agent); agent_to_asset.affineTransform(start, local_start); @@ -331,7 +309,7 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset) gGL.pushMatrix(); // get raycast in asset space - LLMatrix4a agent_to_asset = getAgentToAssetTransform(obj); + LLMatrix4a agent_to_asset = obj->getAgentToGLTFAssetTransform(); LLVector4a start; LLVector4a end; @@ -399,7 +377,8 @@ void GLTFSceneManager::renderDebug() { if (!gPipeline.hasRenderDebugMask( LLPipeline::RENDER_DEBUG_BBOXES | - LLPipeline::RENDER_DEBUG_RAYCAST)) + LLPipeline::RENDER_DEBUG_RAYCAST | + LLPipeline::RENDER_DEBUG_NODES)) { return; } @@ -412,6 +391,7 @@ void GLTFSceneManager::renderDebug() gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gPipeline.disableLights(); + // force update all mRenderMatrix, not just nodes with meshes for (auto& obj : mObjects) { if (obj->isDead() || obj->mGLTFAsset == nullptr) @@ -419,20 +399,115 @@ void GLTFSceneManager::renderDebug() continue; } + LLMatrix4a mat = obj->getGLTFAssetToAgentTransform(); + + LLMatrix4a modelview; + modelview.loadu(gGLModelView); + + matMul(mat, modelview, modelview); + Asset* asset = obj->mGLTFAsset; + for (auto& node : asset->mNodes) + { + matMul(node.mAssetMatrix, modelview, node.mRenderMatrix); + } + } + + for (auto& obj : mObjects) + { + if (obj->isDead() || obj->mGLTFAsset == nullptr) + { + continue; + } + + Asset* asset = obj->mGLTFAsset; - LLMatrix4a mat = getAssetToAgentTransform(obj); + LLMatrix4a mat = obj->getGLTFAssetToAgentTransform(); LLMatrix4a modelview; modelview.loadu(gGLModelView); matMul(mat, modelview, modelview); - asset->updateRenderTransforms(modelview); renderAssetDebug(obj, asset); } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_NODES)) + { //render node hierarchy + + for (U32 i = 0; i < 2; ++i) + { + LLGLDepthTest depth(GL_TRUE, i == 0 ? GL_FALSE : GL_TRUE, i == 0 ? GL_GREATER : GL_LEQUAL); + LLGLState blend(GL_BLEND, i == 0 ? TRUE : FALSE); + + + gGL.pushMatrix(); + + for (auto& obj : mObjects) + { + if (obj->isDead() || obj->mGLTFAsset == nullptr) + { + continue; + } + + LLMatrix4a mat = obj->getGLTFAssetToAgentTransform(); + + LLMatrix4a modelview; + modelview.loadu(gGLModelView); + + matMul(mat, modelview, modelview); + + Asset* asset = obj->mGLTFAsset; + + for (auto& node : asset->mNodes) + { + // force update all mRenderMatrix, not just nodes with meshes + matMul(node.mAssetMatrix, modelview, node.mRenderMatrix); + + gGL.loadMatrix(node.mRenderMatrix.getF32ptr()); + // render x-axis red, y-axis green, z-axis blue + gGL.color4f(1.f, 0.f, 0.f, 0.5f); + gGL.begin(LLRender::LINES); + gGL.vertex3f(0.f, 0.f, 0.f); + gGL.vertex3f(1.f, 0.f, 0.f); + gGL.end(); + gGL.flush(); + + gGL.color4f(0.f, 1.f, 0.f, 0.5f); + gGL.begin(LLRender::LINES); + gGL.vertex3f(0.f, 0.f, 0.f); + gGL.vertex3f(0.f, 1.f, 0.f); + gGL.end(); + gGL.flush(); + + gGL.begin(LLRender::LINES); + gGL.color4f(0.f, 0.f, 1.f, 0.5f); + gGL.vertex3f(0.f, 0.f, 0.f); + gGL.vertex3f(0.f, 0.f, 1.f); + gGL.end(); + gGL.flush(); + + // render path to child nodes cyan + gGL.color4f(0.f, 1.f, 1.f, 0.5f); + gGL.begin(LLRender::LINES); + for (auto& child_idx : node.mChildren) + { + Node& child = asset->mNodes[child_idx]; + gGL.vertex3f(0.f, 0.f, 0.f); + gGL.vertex3fv(child.mMatrix.getTranslation().getF32ptr()); + } + gGL.end(); + gGL.flush(); + } + } + + gGL.popMatrix(); + } + + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST)) { S32 node_hit = -1; -- cgit v1.2.3 From cadc1a02cc7289dabd368dd1a1d237c042e9f82e Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 24 Apr 2024 09:51:15 -0500 Subject: 1285 GLTF Animation Prototype --- indra/newview/gltfscenemanager.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'indra/newview/gltfscenemanager.cpp') diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index 8273c707f9..4e3439ea5c 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -82,6 +82,7 @@ void GLTFSceneManager::load(const std::string& filename) LLPointer asset = new Asset(); *asset = model; + gDebugProgram.bind(); // bind a shader to satisfy LLVertexBuffer assertions asset->allocateGLResources(filename, model); asset->updateTransforms(); @@ -114,7 +115,25 @@ void GLTFSceneManager::renderAlpha() render(false); } -void GLTFSceneManager::render(bool opaque) +void GLTFSceneManager::update() +{ + for (U32 i = 0; i < mObjects.size(); ++i) + { + if (mObjects[i]->isDead() || mObjects[i]->mGLTFAsset == nullptr) + { + mObjects.erase(mObjects.begin() + i); + --i; + continue; + } + + Asset* asset = mObjects[i]->mGLTFAsset; + + asset->update(); + + } +} + +void GLTFSceneManager::render(bool opaque, bool rigged) { // for debugging, just render the whole scene as opaque // by traversing the whole scenegraph @@ -144,7 +163,7 @@ void GLTFSceneManager::render(bool opaque) matMul(mat, modelview, modelview); asset->updateRenderTransforms(modelview); - asset->render(opaque); + asset->render(opaque, rigged); gGL.popMatrix(); } -- cgit v1.2.3 From b06a99f7c76950484972e25d9dbbee8660a6a6c3 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 15 May 2024 12:47:27 +0300 Subject: Post-merge spaces fix --- indra/newview/gltfscenemanager.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'indra/newview/gltfscenemanager.cpp') diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index 4e3439ea5c..7003eab6d0 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -129,7 +129,7 @@ void GLTFSceneManager::update() Asset* asset = mObjects[i]->mGLTFAsset; asset->update(); - + } } @@ -137,9 +137,9 @@ void GLTFSceneManager::render(bool opaque, bool rigged) { // for debugging, just render the whole scene as opaque // by traversing the whole scenegraph - // Assumes camera transform is already set and + // Assumes camera transform is already set and // appropriate shader is already bound - + gGL.matrixMode(LLRender::MM_MODELVIEW); for (U32 i = 0; i < mObjects.size(); ++i) @@ -281,10 +281,10 @@ LLDrawable* GLTFSceneManager::lineSegmentIntersect(const LLVector4a& start, cons LLVector4a* intersection, // return the intersection point LLVector2* tex_coord, // return the texture coordinates of the intersection point LLVector4a* normal, // return the surface normal at the intersection point - LLVector4a* tangent) // return the surface tangent at the intersection point + LLVector4a* tangent) // return the surface tangent at the intersection point { LLDrawable* drawable = nullptr; - + LLVector4a local_end = end; LLVector4a position; @@ -314,8 +314,8 @@ LLDrawable* GLTFSceneManager::lineSegmentIntersect(const LLVector4a& start, cons void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size); -extern LLVector4a gDebugRaycastStart; -extern LLVector4a gDebugRaycastEnd; +extern LLVector4a gDebugRaycastStart; +extern LLVector4a gDebugRaycastEnd; void renderOctreeRaycast(const LLVector4a& start, const LLVector4a& end, const LLVolumeOctree* octree); @@ -336,7 +336,7 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset) agent_to_asset.affineTransform(gDebugRaycastStart, start); agent_to_asset.affineTransform(gDebugRaycastEnd, end); - + for (auto& node : asset->mNodes) { Mesh& mesh = asset->mMeshes[node.mMesh]; @@ -344,7 +344,7 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset) if (node.mMesh != INVALID_INDEX) { gGL.loadMatrix((F32*)node.mRenderMatrix.mMatrix); - + // draw bounding box of mesh primitives if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) { @@ -549,7 +549,7 @@ void GLTFSceneManager::renderDebug() gGL.loadMatrix((F32*) node->mRenderMatrix.mMatrix); - + auto* listener = (LLVolumeOctreeListener*) primitive->mOctree->getListener(0); drawBoxOutline(listener->mBounds[0], listener->mBounds[1]); -- cgit v1.2.3