|
|
@@ -18,6 +18,9 @@
|
|
|
#include "BsRenderable.h"
|
|
|
#include "BsSceneManager.h"
|
|
|
#include "BsRendererUtility.h"
|
|
|
+#include "BsAnimationManager.h"
|
|
|
+#include "BsSkeleton.h"
|
|
|
+#include "BsGpuBuffer.h"
|
|
|
|
|
|
using namespace std::placeholders;
|
|
|
|
|
|
@@ -50,7 +53,7 @@ namespace BansheeEngine
|
|
|
|
|
|
void SelectionRenderer::update(const SPtr<Camera>& camera)
|
|
|
{
|
|
|
- Vector<ObjectData> objects;
|
|
|
+ Vector<SPtr<RenderableCore>> objects;
|
|
|
|
|
|
const Vector<HSceneObject>& sceneObjects = Selection::instance().getSceneObjects();
|
|
|
const Map<Renderable*, SceneRenderableData>& renderables = SceneManager::instance().getAllRenderables();
|
|
|
@@ -66,13 +69,7 @@ namespace BansheeEngine
|
|
|
continue;
|
|
|
|
|
|
if (renderable.first->getMesh().isLoaded())
|
|
|
- {
|
|
|
- objects.push_back(ObjectData());
|
|
|
-
|
|
|
- ObjectData& newObjData = objects.back();
|
|
|
- newObjData.worldTfrm = so->getWorldTfrm();
|
|
|
- newObjData.mesh = renderable.first->getMesh()->getCore();
|
|
|
- }
|
|
|
+ objects.push_back(renderable.first->getCore());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -97,17 +94,29 @@ namespace BansheeEngine
|
|
|
{
|
|
|
THROW_IF_NOT_CORE_THREAD;
|
|
|
|
|
|
+ mDefaultTechniqueIdx = mat->getDefaultTechnique();
|
|
|
+ mAnimatedTechniqueIdx = mat->findTechnique(RTag_Animated);
|
|
|
+
|
|
|
+ assert(mDefaultTechniqueIdx < 2 && mAnimatedTechniqueIdx < 2);
|
|
|
+
|
|
|
mMaterial = mat;
|
|
|
- mParams = mat->createParamsSet();
|
|
|
|
|
|
- SPtr<GpuParamsCore> vertParams = mParams->getGpuParams(GPT_VERTEX_PROGRAM);
|
|
|
- vertParams->getParam("matWorldViewProj", mMatWorldViewProj);
|
|
|
+ for(UINT32 i = 0; i < 2 ; i++)
|
|
|
+ {
|
|
|
+ mParams[i] = mat->createParamsSet(i);
|
|
|
|
|
|
- SPtr<GpuParamsCore> fragParams = mParams->getGpuParams(GPT_FRAGMENT_PROGRAM);
|
|
|
- fragParams->getParam("selColor", mColor);
|
|
|
+ SPtr<GpuParamsCore> vertParams = mParams[i]->getGpuParams(GPT_VERTEX_PROGRAM);
|
|
|
+ vertParams->getParam("matWorldViewProj", mMatWorldViewProj[i]);
|
|
|
+
|
|
|
+ SPtr<GpuParamsCore> fragParams = mParams[i]->getGpuParams(GPT_FRAGMENT_PROGRAM);
|
|
|
+ fragParams->getParam("selColor", mColor[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ SPtr<GpuParamsCore> vertParams = mParams[mAnimatedTechniqueIdx]->getGpuParams(GPT_VERTEX_PROGRAM);
|
|
|
+ vertParams->getBufferParam("boneMatrices", mBoneMatrices);
|
|
|
}
|
|
|
|
|
|
- void SelectionRendererCore::updateData(const SPtr<CameraCore>& camera, const Vector<SelectionRenderer::ObjectData>& objects)
|
|
|
+ void SelectionRendererCore::updateData(const SPtr<CameraCore>& camera, const Vector<SPtr<RenderableCore>>& objects)
|
|
|
{
|
|
|
if (mCamera != camera)
|
|
|
{
|
|
|
@@ -130,22 +139,60 @@ namespace BansheeEngine
|
|
|
if (mCamera == nullptr)
|
|
|
return;
|
|
|
|
|
|
+ const RendererAnimationData& animData = AnimationManager::instance().getRendererData();
|
|
|
Matrix4 viewProjMat = mCamera->getProjectionMatrixRS() * mCamera->getViewMatrix();
|
|
|
|
|
|
- for (auto& objData : mObjects)
|
|
|
+ for (auto& renderable : mObjects)
|
|
|
{
|
|
|
- Matrix4 worldViewProjMat = viewProjMat * objData.worldTfrm;
|
|
|
+ SPtr<MeshCore> mesh = renderable->getMesh();
|
|
|
+ if (mesh == nullptr)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ Matrix4 worldViewProjMat = viewProjMat * renderable->getTransform();
|
|
|
+ UINT32 techniqueIdx = renderable->isAnimated() ? mAnimatedTechniqueIdx : mDefaultTechniqueIdx;
|
|
|
+
|
|
|
+ mMatWorldViewProj[techniqueIdx].set(worldViewProjMat);
|
|
|
+ mColor[techniqueIdx].set(SELECTION_COLOR);
|
|
|
|
|
|
- mMatWorldViewProj.set(worldViewProjMat);
|
|
|
- mColor.set(SELECTION_COLOR);
|
|
|
+ if(renderable->isAnimated())
|
|
|
+ {
|
|
|
+ SPtr<Skeleton> skeleton = mesh->getSkeleton();
|
|
|
+ UINT32 numBones = skeleton != nullptr ? skeleton->getNumBones() : 0;
|
|
|
+
|
|
|
+ if (numBones > 0)
|
|
|
+ {
|
|
|
+ // Note: If I had access to them I could just use the buffers from the Renderer instead of creating a
|
|
|
+ // new one every frame
|
|
|
+ SPtr<GpuBufferCore> buffer = GpuBufferCore::create(numBones * 3, 0, GBT_STANDARD, BF_32X4F, GBU_DYNAMIC);
|
|
|
+
|
|
|
+ auto iterFind = animData.poseInfos.find(renderable->getAnimationId());
|
|
|
+ if (iterFind != animData.poseInfos.end())
|
|
|
+ {
|
|
|
+ const RendererAnimationData::PoseInfo& poseInfo = iterFind->second;
|
|
|
+
|
|
|
+ UINT8* dest = (UINT8*)buffer->lock(0, poseInfo.numBones * 3 * sizeof(Vector4), GBL_WRITE_ONLY_DISCARD);
|
|
|
+ for (UINT32 j = 0; j < poseInfo.numBones; j++)
|
|
|
+ {
|
|
|
+ const Matrix4& transform = animData.transforms[poseInfo.startIdx + j];
|
|
|
+ memcpy(dest, &transform, 12 * sizeof(float)); // Assuming row-major format
|
|
|
+
|
|
|
+ dest += 12 * sizeof(float);
|
|
|
+ }
|
|
|
+
|
|
|
+ buffer->unlock();
|
|
|
+ }
|
|
|
+
|
|
|
+ mBoneMatrices.set(buffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- gRendererUtility().setPass(mMaterial, 0);
|
|
|
- gRendererUtility().setPassParams(mParams, 0);
|
|
|
+ gRendererUtility().setPass(mMaterial, 0, techniqueIdx);
|
|
|
+ gRendererUtility().setPassParams(mParams[techniqueIdx], 0);
|
|
|
|
|
|
- UINT32 numSubmeshes = objData.mesh->getProperties().getNumSubMeshes();
|
|
|
+ UINT32 numSubmeshes = mesh->getProperties().getNumSubMeshes();
|
|
|
|
|
|
for (UINT32 i = 0; i < numSubmeshes; i++)
|
|
|
- gRendererUtility().draw(objData.mesh, objData.mesh->getProperties().getSubMesh(i));
|
|
|
+ gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(i));
|
|
|
}
|
|
|
}
|
|
|
}
|