From 15740faf9fe9fe4be08965098bbf2947e096aeeb Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 14 Aug 2019 22:50:43 +0800 Subject: +Unity Runtime code --- Runtime/Filters/Mesh/MeshBlendShape.cpp | 234 ++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 Runtime/Filters/Mesh/MeshBlendShape.cpp (limited to 'Runtime/Filters/Mesh/MeshBlendShape.cpp') diff --git a/Runtime/Filters/Mesh/MeshBlendShape.cpp b/Runtime/Filters/Mesh/MeshBlendShape.cpp new file mode 100644 index 0000000..c7588e2 --- /dev/null +++ b/Runtime/Filters/Mesh/MeshBlendShape.cpp @@ -0,0 +1,234 @@ +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "MeshBlendShape.h" +#include "Runtime/mecanim/generic/crc32.h" + +static const float kVertexDeltaEpsilon = 1e-5f; +static const float kNormalDeltaEpsilon = 1e-5f; + +void SetBlendShapeVertices(const std::vector& deltaVertices, const std::vector& deltaNormals, const std::vector& deltaTangents, BlendShapeVertices& sharedSparceVertices, BlendShape& frame) +{ + Assert(deltaNormals.empty() || deltaVertices.size() == deltaNormals.size()); + Assert(deltaTangents.empty() || deltaVertices.size() == deltaTangents.size()); + + frame.firstVertex = sharedSparceVertices.size(); + + // Converting blend shape in to sparse blend shape + sharedSparceVertices.reserve(sharedSparceVertices.size() + deltaVertices.size()); + + frame.hasNormals = frame.hasTangents = false; + + for (int j = 0; j < deltaVertices.size(); ++j) + { + const bool vertexHasNormal = (!deltaNormals.empty() && Magnitude(deltaNormals[j]) > kNormalDeltaEpsilon); + const bool vertexHasTangent = (!deltaTangents.empty() && Magnitude(deltaTangents[j]) > kNormalDeltaEpsilon); + + frame.hasNormals = frame.hasNormals || vertexHasNormal; + frame.hasTangents = frame.hasTangents || vertexHasTangent; + + if (Magnitude(deltaVertices[j]) > kVertexDeltaEpsilon || vertexHasNormal || vertexHasTangent) + { + BlendShapeVertex v; + + v.vertex = deltaVertices[j]; + if (!deltaNormals.empty()) + v.normal = deltaNormals[j]; + if (!deltaTangents.empty()) + v.tangent = deltaTangents[j]; + + v.index = j; + sharedSparceVertices.push_back(v); + } + } + + frame.vertexCount = sharedSparceVertices.size() - frame.firstVertex; +} + +void BlendShape::UpdateFlags(const BlendShapeVertices& sharedSparceVertices) +{ + hasNormals = hasTangents = false; + + for (int j = 0; j < vertexCount; ++j) + { + const BlendShapeVertex& v = sharedSparceVertices[firstVertex + j]; + const bool vertexHasNormal = Magnitude(v.normal) > kNormalDeltaEpsilon; + const bool vertexHasTangent = Magnitude(v.tangent) > kNormalDeltaEpsilon; + + hasNormals = hasNormals || vertexHasNormal; + hasTangents = hasTangents || vertexHasTangent; + } +} + +void InitializeChannel (const UnityStr& inName, int frameIndex, int frameCount, BlendShapeChannel& channel) +{ + channel.name.assign(inName.c_str(), kMemGeometry); + channel.nameHash = mecanim::processCRC32(inName.c_str()); + channel.frameIndex = frameIndex; + channel.frameCount = frameCount; +} + +const char* GetChannelName (const BlendShapeData& data, int index) +{ + return data.channels[index].name.c_str(); +} + +int GetChannelIndex (const BlendShapeData& data, const char* name) +{ + for (int i=0;i(vertices, classVertex, BlendShapeVertexToMono); + } + + private: + const BlendShapeVertices& sharedVertices; + }; + + class MeshBlendShapeToCpp + { + public: + MeshBlendShapeToCpp(int meshVertexCount_, BlendShapeVertices& sharedVertices_) : meshVertexCount(meshVertexCount_), sharedVertices(sharedVertices_) {} + + void operator() (MonoMeshBlendShape &src, MeshBlendShape &dest) + { + dest.weight = src.weight; + + const BlendShapeVertex* vertices = Scripting::GetScriptingArrayStart (src.vertices); + sharedVertices.insert(sharedVertices.end(), vertices, vertices + GetScriptingArraySize(src.vertices)); + + for (BlendShapeVertices::iterator it = vertices.begin(), end = vertices.end(); it != end; ++it) + { + BlendShapeVertex& v = *it; + if (v.index < 0 || v.index >= meshVertexCount) + { + ErrorStringMsg("Value (%d) of BlendShapeVertex.index #%d is out of bounds (Mesh vertex count: %d) on BlendShape '%s'. It will be reset to 0.", v.index, it - vertices.begin(), meshVertexCount, dest.m_Name.c_str()); + v.index = 0; + } + } + + dest.firstVertex = sharedVertices.size(); + dest.vertexCount = vertices.size(); + + sharedVertices.insert(sharedVertices.end(), vertices.begin(), vertices.end()); + dest.UpdateFlags(sharedVertices); + } + + private: + int meshVertexCount; + BlendShapeVertices& sharedVertices; + }; + + + + ---------------- + + // BlendShapes for this mesh. + CUSTOM_PROP BlendShapeChannel[] blendShapes + { + // ScriptingTypePtr classBlendShape = GetScriptingTypeRegistry().GetType("UnityEngine", "MeshBlendShape"); + // return VectorToScriptingStructArray(self->GetShapesVector(), classBlendShape, MeshBlendShapeToMono(self->GetShapeVertexVector())); + return SCRIPTING_NULL; + } + { + // Mesh::MeshBlendShapeContainer shapes; + // self->GetShapeVertexVector().clear(); + // ScriptingStructArrayToVector(value, shapes, MeshBlendShapeToCpp(self->GetVertexCount(), self->GetShapeVertexVector())); + // self->SwapShapesVector(shapes); + } + + + + */ -- cgit v1.1-26-g67d0