Refactor engine to support double-precision vectors
This commit is contained in:
@@ -26,8 +26,7 @@ void MeshAccelerationStructure::BuildBVH(int32 node, int32 maxLeafSize, Array<by
|
||||
right.Leaf.MeshIndex = root.Leaf.MeshIndex;
|
||||
|
||||
// Mid-point splitting based on the largest axis
|
||||
Vector3 boundsSize;
|
||||
root.Bounds.GetSize(boundsSize);
|
||||
const Float3 boundsSize = root.Bounds.GetSize();
|
||||
int32 axisCount = 0;
|
||||
int32 axis = 0;
|
||||
RETRY:
|
||||
@@ -51,9 +50,9 @@ RETRY:
|
||||
// Go to the next axis
|
||||
axis = (axis + 1) % 3;
|
||||
}
|
||||
const float midPoint = root.Bounds.Minimum.Raw[axis] + boundsSize.Raw[axis] * 0.5f;
|
||||
const float midPoint = (float)(root.Bounds.Minimum.Raw[axis] + boundsSize.Raw[axis] * 0.5f);
|
||||
const Mesh& meshData = _meshes[root.Leaf.MeshIndex];
|
||||
const Vector3* vb = meshData.VertexBuffer.Get<Vector3>();
|
||||
const Float3* vb = meshData.VertexBuffer.Get<Float3>();
|
||||
int32 indexStart = root.Leaf.TriangleIndex * 3;
|
||||
int32 indexEnd = indexStart + root.Leaf.TriangleCount * 3;
|
||||
left.Leaf.TriangleCount = 0;
|
||||
@@ -152,7 +151,7 @@ RETRY:
|
||||
BuildBVH(childIndex + 1, maxLeafSize, scratch);
|
||||
}
|
||||
|
||||
bool MeshAccelerationStructure::PointQueryBVH(int32 node, const Vector3& point, float& hitDistance, Vector3& hitPoint, Triangle& hitTriangle) const
|
||||
bool MeshAccelerationStructure::PointQueryBVH(int32 node, const Vector3& point, Real& hitDistance, Vector3& hitPoint, Triangle& hitTriangle) const
|
||||
{
|
||||
const auto& root = _bvh[node];
|
||||
bool hit = false;
|
||||
@@ -161,7 +160,7 @@ bool MeshAccelerationStructure::PointQueryBVH(int32 node, const Vector3& point,
|
||||
// Find closest triangle
|
||||
Vector3 p;
|
||||
const Mesh& meshData = _meshes[root.Leaf.MeshIndex];
|
||||
const Vector3* vb = meshData.VertexBuffer.Get<Vector3>();
|
||||
const Float3* vb = meshData.VertexBuffer.Get<Float3>();
|
||||
const int32 indexStart = root.Leaf.TriangleIndex * 3;
|
||||
const int32 indexEnd = indexStart + root.Leaf.TriangleCount * 3;
|
||||
if (meshData.Use16BitIndexBuffer)
|
||||
@@ -173,7 +172,7 @@ bool MeshAccelerationStructure::PointQueryBVH(int32 node, const Vector3& point,
|
||||
Vector3 v1 = vb[ib16[i++]];
|
||||
Vector3 v2 = vb[ib16[i++]];
|
||||
CollisionsHelper::ClosestPointPointTriangle(point, v0, v1, v2, p);
|
||||
const float distance = Vector3::Distance(point, p);
|
||||
const Real distance = Vector3::Distance(point, p);
|
||||
if (distance < hitDistance)
|
||||
{
|
||||
hitDistance = distance;
|
||||
@@ -192,7 +191,7 @@ bool MeshAccelerationStructure::PointQueryBVH(int32 node, const Vector3& point,
|
||||
Vector3 v1 = vb[ib32[i++]];
|
||||
Vector3 v2 = vb[ib32[i++]];
|
||||
CollisionsHelper::ClosestPointPointTriangle(point, v0, v1, v2, p);
|
||||
const float distance = Vector3::Distance(point, p);
|
||||
const Real distance = Vector3::Distance(point, p);
|
||||
if (distance < hitDistance)
|
||||
{
|
||||
hitDistance = distance;
|
||||
@@ -218,19 +217,19 @@ bool MeshAccelerationStructure::PointQueryBVH(int32 node, const Vector3& point,
|
||||
return hit;
|
||||
}
|
||||
|
||||
bool MeshAccelerationStructure::RayCastBVH(int32 node, const Ray& ray, float& hitDistance, Vector3& hitNormal, Triangle& hitTriangle) const
|
||||
bool MeshAccelerationStructure::RayCastBVH(int32 node, const Ray& ray, Real& hitDistance, Vector3& hitNormal, Triangle& hitTriangle) const
|
||||
{
|
||||
const auto& root = _bvh[node];
|
||||
if (!root.Bounds.Intersects(ray))
|
||||
return false;
|
||||
Vector3 normal;
|
||||
float distance;
|
||||
Real distance;
|
||||
bool hit = false;
|
||||
if (root.Leaf.IsLeaf)
|
||||
{
|
||||
// Ray cast along triangles in the leaf
|
||||
const Mesh& meshData = _meshes[root.Leaf.MeshIndex];
|
||||
const Vector3* vb = meshData.VertexBuffer.Get<Vector3>();
|
||||
const Float3* vb = meshData.VertexBuffer.Get<Float3>();
|
||||
const int32 indexStart = root.Leaf.TriangleIndex * 3;
|
||||
const int32 indexEnd = indexStart + root.Leaf.TriangleCount * 3;
|
||||
if (meshData.Use16BitIndexBuffer)
|
||||
@@ -343,28 +342,28 @@ void MeshAccelerationStructure::Add(ModelData* modelData, int32 lodIndex, bool c
|
||||
if (copy)
|
||||
{
|
||||
meshData.IndexBuffer.Copy((const byte*)mesh->Indices.Get(), meshData.Indices * sizeof(uint32));
|
||||
meshData.VertexBuffer.Copy((const byte*)mesh->Positions.Get(), meshData.Vertices * sizeof(Vector3));
|
||||
meshData.VertexBuffer.Copy((const byte*)mesh->Positions.Get(), meshData.Vertices * sizeof(Float3));
|
||||
}
|
||||
else
|
||||
{
|
||||
meshData.IndexBuffer.Link((const byte*)mesh->Indices.Get(), meshData.Indices * sizeof(uint32));
|
||||
meshData.VertexBuffer.Link((const byte*)mesh->Positions.Get(), meshData.Vertices * sizeof(Vector3));
|
||||
meshData.VertexBuffer.Link((const byte*)mesh->Positions.Get(), meshData.Vertices * sizeof(Float3));
|
||||
}
|
||||
meshData.Use16BitIndexBuffer = false;
|
||||
mesh->CalculateBox(meshData.Bounds);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshAccelerationStructure::Add(Vector3* vb, int32 vertices, void* ib, int32 indices, bool use16BitIndex, bool copy)
|
||||
void MeshAccelerationStructure::Add(Float3* vb, int32 vertices, void* ib, int32 indices, bool use16BitIndex, bool copy)
|
||||
{
|
||||
auto& meshData = _meshes.AddOne();
|
||||
if (copy)
|
||||
{
|
||||
meshData.VertexBuffer.Copy((const byte*)vb, vertices * sizeof(Vector3));
|
||||
meshData.VertexBuffer.Copy((const byte*)vb, vertices * sizeof(Float3));
|
||||
}
|
||||
else
|
||||
{
|
||||
meshData.VertexBuffer.Link((const byte*)vb, vertices * sizeof(Vector3));
|
||||
meshData.VertexBuffer.Link((const byte*)vb, vertices * sizeof(Float3));
|
||||
}
|
||||
meshData.IndexBuffer.Copy((const byte*)ib, indices * (use16BitIndex ? sizeof(uint16) : sizeof(uint32)));
|
||||
meshData.Vertices = vertices;
|
||||
@@ -409,9 +408,9 @@ void MeshAccelerationStructure::BuildBVH(int32 maxLeafSize)
|
||||
BuildBVH(i + 1, maxLeafSize, scratch);
|
||||
}
|
||||
|
||||
bool MeshAccelerationStructure::PointQuery(const Vector3& point, float& hitDistance, Vector3& hitPoint, Triangle& hitTriangle, float maxDistance) const
|
||||
bool MeshAccelerationStructure::PointQuery(const Vector3& point, Real& hitDistance, Vector3& hitPoint, Triangle& hitTriangle, Real maxDistance) const
|
||||
{
|
||||
hitDistance = maxDistance >= MAX_float ? maxDistance : maxDistance * maxDistance;
|
||||
hitDistance = maxDistance >= MAX_Real ? maxDistance : maxDistance * maxDistance;
|
||||
bool hit = false;
|
||||
|
||||
// BVH
|
||||
@@ -449,7 +448,7 @@ bool MeshAccelerationStructure::PointQuery(const Vector3& point, float& hitDista
|
||||
Vector3 p;
|
||||
for (const Mesh& meshData : _meshes)
|
||||
{
|
||||
const Vector3* vb = meshData.VertexBuffer.Get<Vector3>();
|
||||
const Float3* vb = meshData.VertexBuffer.Get<Float3>();
|
||||
if (meshData.Use16BitIndexBuffer)
|
||||
{
|
||||
const uint16* ib16 = meshData.IndexBuffer.Get<uint16>();
|
||||
@@ -459,7 +458,7 @@ bool MeshAccelerationStructure::PointQuery(const Vector3& point, float& hitDista
|
||||
Vector3 v1 = vb[ib16[i++]];
|
||||
Vector3 v2 = vb[ib16[i++]];
|
||||
CollisionsHelper::ClosestPointPointTriangle(point, v0, v1, v2, p);
|
||||
const float distance = Vector3::DistanceSquared(point, p);
|
||||
const Real distance = Vector3::DistanceSquared(point, p);
|
||||
if (distance < hitDistance)
|
||||
{
|
||||
hitDistance = distance;
|
||||
@@ -478,7 +477,7 @@ bool MeshAccelerationStructure::PointQuery(const Vector3& point, float& hitDista
|
||||
Vector3 v1 = vb[ib32[i++]];
|
||||
Vector3 v2 = vb[ib32[i++]];
|
||||
CollisionsHelper::ClosestPointPointTriangle(point, v0, v1, v2, p);
|
||||
const float distance = Vector3::DistanceSquared(point, p);
|
||||
const Real distance = Vector3::DistanceSquared(point, p);
|
||||
if (distance < hitDistance)
|
||||
{
|
||||
hitDistance = distance;
|
||||
@@ -495,7 +494,7 @@ bool MeshAccelerationStructure::PointQuery(const Vector3& point, float& hitDista
|
||||
}
|
||||
}
|
||||
|
||||
bool MeshAccelerationStructure::RayCast(const Ray& ray, float& hitDistance, Vector3& hitNormal, Triangle& hitTriangle, float maxDistance) const
|
||||
bool MeshAccelerationStructure::RayCast(const Ray& ray, Real& hitDistance, Vector3& hitNormal, Triangle& hitTriangle, Real maxDistance) const
|
||||
{
|
||||
hitDistance = maxDistance;
|
||||
|
||||
@@ -508,13 +507,13 @@ bool MeshAccelerationStructure::RayCast(const Ray& ray, float& hitDistance, Vect
|
||||
// Brute-force
|
||||
{
|
||||
Vector3 normal;
|
||||
float distance;
|
||||
Real distance;
|
||||
bool hit = false;
|
||||
for (const Mesh& meshData : _meshes)
|
||||
{
|
||||
if (!meshData.Bounds.Intersects(ray))
|
||||
continue;
|
||||
const Vector3* vb = meshData.VertexBuffer.Get<Vector3>();
|
||||
const Float3* vb = meshData.VertexBuffer.Get<Float3>();
|
||||
if (meshData.Use16BitIndexBuffer)
|
||||
{
|
||||
const uint16* ib16 = meshData.IndexBuffer.Get<uint16>();
|
||||
|
||||
@@ -53,8 +53,8 @@ private:
|
||||
Array<BVH> _bvh;
|
||||
|
||||
void BuildBVH(int32 node, int32 maxLeafSize, Array<byte>& scratch);
|
||||
bool PointQueryBVH(int32 node, const Vector3& point, float& hitDistance, Vector3& hitPoint, Triangle& hitTriangle) const;
|
||||
bool RayCastBVH(int32 node, const Ray& ray, float& hitDistance, Vector3& hitNormal, Triangle& hitTriangle) const;
|
||||
bool PointQueryBVH(int32 node, const Vector3& point, Real& hitDistance, Vector3& hitPoint, Triangle& hitTriangle) const;
|
||||
bool RayCastBVH(int32 node, const Ray& ray, Real& hitDistance, Vector3& hitNormal, Triangle& hitTriangle) const;
|
||||
|
||||
public:
|
||||
// Adds the model geometry for the build to the structure.
|
||||
@@ -64,16 +64,16 @@ public:
|
||||
void Add(ModelData* modelData, int32 lodIndex, bool copy = false);
|
||||
|
||||
// Adds the triangles geometry for the build to the structure.
|
||||
void Add(Vector3* vb, int32 vertices, void* ib, int32 indices, bool use16BitIndex, bool copy = false);
|
||||
void Add(Float3* vb, int32 vertices, void* ib, int32 indices, bool use16BitIndex, bool copy = false);
|
||||
|
||||
// Builds Bounding Volume Hierarchy (BVH) structure for accelerated geometry queries.
|
||||
void BuildBVH(int32 maxLeafSize = 16);
|
||||
|
||||
// Queries the closest triangle.
|
||||
bool PointQuery(const Vector3& point, float& hitDistance, Vector3& hitPoint, Triangle& hitTriangle, float maxDistance = MAX_float) const;
|
||||
bool PointQuery(const Vector3& point, Real& hitDistance, Vector3& hitPoint, Triangle& hitTriangle, Real maxDistance = MAX_Real) const;
|
||||
|
||||
// Ray traces the triangles.
|
||||
bool RayCast(const Ray& ray, float& hitDistance, Vector3& hitNormal, Triangle& hitTriangle, float maxDistance = MAX_float) const;
|
||||
bool RayCast(const Ray& ray, Real& hitDistance, Vector3& hitNormal, Triangle& hitTriangle, Real maxDistance = MAX_Real) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -47,19 +47,19 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
Vector2 ToVector2(const aiVector2D& v)
|
||||
Float2 ToFloat2(const aiVector2D& v)
|
||||
{
|
||||
return Vector2(v.x, v.y);
|
||||
return Float2(v.x, v.y);
|
||||
}
|
||||
|
||||
Vector2 ToVector2(const aiVector3D& v)
|
||||
Float2 ToFloat2(const aiVector3D& v)
|
||||
{
|
||||
return Vector2(v.x, v.y);
|
||||
return Float2(v.x, v.y);
|
||||
}
|
||||
|
||||
Vector3 ToVector3(const aiVector3D& v)
|
||||
Float3 ToFloat3(const aiVector3D& v)
|
||||
{
|
||||
return Vector3(v.x, v.y, v.z);
|
||||
return Float3(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
Color ToColor(const aiColor3D& v)
|
||||
@@ -234,7 +234,7 @@ bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMe
|
||||
mesh.MaterialSlotIndex = aMesh->mMaterialIndex;
|
||||
|
||||
// Vertex positions
|
||||
mesh.Positions.Set((const Vector3*)aMesh->mVertices, aMesh->mNumVertices);
|
||||
mesh.Positions.Set((const Float3*)aMesh->mVertices, aMesh->mNumVertices);
|
||||
|
||||
// Texture coordinates
|
||||
if (aMesh->mTextureCoords[0])
|
||||
@@ -243,7 +243,7 @@ bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMe
|
||||
aiVector3D* a = aMesh->mTextureCoords[0];
|
||||
for (uint32 v = 0; v < aMesh->mNumVertices; v++)
|
||||
{
|
||||
mesh.UVs[v] = *(Vector2*)a;
|
||||
mesh.UVs[v] = *(Float2*)a;
|
||||
a++;
|
||||
}
|
||||
}
|
||||
@@ -251,13 +251,13 @@ bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMe
|
||||
// Normals
|
||||
if (aMesh->mNormals)
|
||||
{
|
||||
mesh.Normals.Set((const Vector3*)aMesh->mNormals, aMesh->mNumVertices);
|
||||
mesh.Normals.Set((const Float3*)aMesh->mNormals, aMesh->mNumVertices);
|
||||
}
|
||||
|
||||
// Tangents
|
||||
if (aMesh->mTangents)
|
||||
{
|
||||
mesh.Tangents.Set((const Vector3*)aMesh->mTangents, aMesh->mNumVertices);
|
||||
mesh.Tangents.Set((const Float3*)aMesh->mTangents, aMesh->mNumVertices);
|
||||
}
|
||||
|
||||
// Indices
|
||||
@@ -320,7 +320,7 @@ bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMe
|
||||
aiVector3D* a = aMesh->mTextureCoords[inputChannelIndex];
|
||||
for (uint32 v = 0; v < aMesh->mNumVertices; v++)
|
||||
{
|
||||
mesh.LightmapUVs[v] = *(Vector2*)a;
|
||||
mesh.LightmapUVs[v] = *(Float2*)a;
|
||||
a++;
|
||||
}
|
||||
}
|
||||
@@ -349,7 +349,7 @@ bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMe
|
||||
mesh.BlendIndices.Resize(vertexCount);
|
||||
mesh.BlendWeights.Resize(vertexCount);
|
||||
mesh.BlendIndices.SetAll(Int4::Zero);
|
||||
mesh.BlendWeights.SetAll(Vector4::Zero);
|
||||
mesh.BlendWeights.SetAll(Float4::Zero);
|
||||
|
||||
// Build skinning clusters and fill controls points data structure
|
||||
for (unsigned boneId = 0; boneId < aMesh->mNumBones; boneId++)
|
||||
@@ -444,24 +444,24 @@ bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMe
|
||||
if (shapeVertices)
|
||||
{
|
||||
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
||||
blendShapeData.Vertices[i].PositionDelta = ToVector3(shapeVertices[i]) - mesh.Positions[i];
|
||||
blendShapeData.Vertices[i].PositionDelta = ToFloat3(shapeVertices[i]) - mesh.Positions[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
||||
blendShapeData.Vertices[i].PositionDelta = Vector3::Zero;
|
||||
blendShapeData.Vertices[i].PositionDelta = Float3::Zero;
|
||||
}
|
||||
|
||||
const aiVector3D* shapeNormals = aAnimMesh->mNormals;
|
||||
if (shapeNormals)
|
||||
{
|
||||
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
||||
blendShapeData.Vertices[i].NormalDelta = ToVector3(shapeNormals[i]) - mesh.Normals[i];
|
||||
blendShapeData.Vertices[i].NormalDelta = ToFloat3(shapeNormals[i]) - mesh.Normals[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
||||
blendShapeData.Vertices[i].NormalDelta = Vector3::Zero;
|
||||
blendShapeData.Vertices[i].NormalDelta = Float3::Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -587,7 +587,7 @@ bool ImportMesh(int32 i, ImportedModelData& result, AssimpImporterData& data, St
|
||||
return false;
|
||||
}
|
||||
|
||||
void ImportCurve(aiVectorKey* keys, uint32 keysCount, LinearCurve<Vector3>& curve)
|
||||
void ImportCurve(aiVectorKey* keys, uint32 keysCount, LinearCurve<Float3>& curve)
|
||||
{
|
||||
if (keys == nullptr || keysCount == 0)
|
||||
return;
|
||||
@@ -600,7 +600,7 @@ void ImportCurve(aiVectorKey* keys, uint32 keysCount, LinearCurve<Vector3>& curv
|
||||
auto& key = keyframes[i];
|
||||
|
||||
key.Time = (float)aKey.mTime;
|
||||
key.Value = ToVector3(aKey.mValue);
|
||||
key.Value = ToFloat3(aKey.mValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,36 +49,32 @@ Matrix ToFlaxType(const FbxAMatrix& value)
|
||||
for (int32 row = 0; row < 4; row++)
|
||||
for (int32 col = 0; col < 4; col++)
|
||||
native.Values[row][col] = (float)value[col][row];
|
||||
|
||||
return native;
|
||||
}
|
||||
|
||||
Vector3 ToFlaxType(const FbxVector4& value)
|
||||
Float3 ToFlaxType(const FbxVector4& value)
|
||||
{
|
||||
Vector3 native;
|
||||
Float3 native;
|
||||
native.X = (float)value[0];
|
||||
native.Y = (float)value[1];
|
||||
native.Z = (float)value[2];
|
||||
|
||||
return native;
|
||||
}
|
||||
|
||||
Vector3 ToFlaxType(const FbxDouble3& value)
|
||||
Float3 ToFlaxType(const FbxDouble3& value)
|
||||
{
|
||||
Vector3 native;
|
||||
Float3 native;
|
||||
native.X = (float)value[0];
|
||||
native.Y = (float)value[1];
|
||||
native.Z = (float)value[2];
|
||||
|
||||
return native;
|
||||
}
|
||||
|
||||
Vector2 ToFlaxType(const FbxVector2& value)
|
||||
Float2 ToFlaxType(const FbxVector2& value)
|
||||
{
|
||||
Vector2 native;
|
||||
Float2 native;
|
||||
native.X = (float)value[0];
|
||||
native.Y = 1 - (float)value[1];
|
||||
|
||||
return native;
|
||||
}
|
||||
|
||||
@@ -89,7 +85,6 @@ Color ToFlaxType(const FbxColor& value)
|
||||
native.G = (float)value[1];
|
||||
native.B = (float)value[2];
|
||||
native.A = (float)value[3];
|
||||
|
||||
return native;
|
||||
}
|
||||
|
||||
@@ -218,9 +213,9 @@ void ProcessNodes(ImporterData& data, FbxNode* fbxNode, int32 parentIndex)
|
||||
{
|
||||
const int32 nodeIndex = data.Nodes.Count();
|
||||
|
||||
Vector3 translation = ToFlaxType(fbxNode->EvaluateLocalTranslation(FbxTime(0)));
|
||||
Vector3 rotationEuler = ToFlaxType(fbxNode->EvaluateLocalRotation(FbxTime(0)));
|
||||
Vector3 scale = ToFlaxType(fbxNode->EvaluateLocalScaling(FbxTime(0)));
|
||||
Float3 translation = ToFlaxType(fbxNode->EvaluateLocalTranslation(FbxTime(0)));
|
||||
Float3 rotationEuler = ToFlaxType(fbxNode->EvaluateLocalRotation(FbxTime(0)));
|
||||
Float3 scale = ToFlaxType(fbxNode->EvaluateLocalScaling(FbxTime(0)));
|
||||
Quaternion rotation = Quaternion::Euler(rotationEuler);
|
||||
|
||||
// Create node
|
||||
@@ -231,9 +226,9 @@ void ProcessNodes(ImporterData& data, FbxNode* fbxNode, int32 parentIndex)
|
||||
node.FbxNode = fbxNode;
|
||||
|
||||
// Geometry transform is applied to geometry (mesh data) only, it is not inherited by children, so we store it separately
|
||||
Vector3 geomTrans = ToFlaxType(fbxNode->GeometricTranslation.Get());
|
||||
Vector3 geomRotEuler = ToFlaxType(fbxNode->GeometricRotation.Get());
|
||||
Vector3 geomScale = ToFlaxType(fbxNode->GeometricScaling.Get());
|
||||
Float3 geomTrans = ToFlaxType(fbxNode->GeometricTranslation.Get());
|
||||
Float3 geomRotEuler = ToFlaxType(fbxNode->GeometricRotation.Get());
|
||||
Float3 geomScale = ToFlaxType(fbxNode->GeometricScaling.Get());
|
||||
Quaternion geomRotation = Quaternion::Euler(geomRotEuler);
|
||||
Transform(geomTrans, geomRotation, geomScale).GetWorld(node.GeomTransform);
|
||||
|
||||
@@ -473,7 +468,7 @@ bool ProcessMesh(ImporterData& data, FbxMesh* fbxMesh, MeshData& mesh, String& e
|
||||
mesh.BlendIndices.Resize(vertexCount);
|
||||
mesh.BlendWeights.Resize(vertexCount);
|
||||
mesh.BlendIndices.SetAll(Int4::Zero);
|
||||
mesh.BlendWeights.SetAll(Vector4::Zero);
|
||||
mesh.BlendWeights.SetAll(Float4::Zero);
|
||||
|
||||
for (int deformerIndex = 0; deformerIndex < skinDeformerCount; deformerIndex++)
|
||||
{
|
||||
@@ -608,7 +603,7 @@ bool ProcessMesh(ImporterData& data, FbxMesh* fbxMesh, MeshData& mesh, String& e
|
||||
blendShapeData.Vertices[i].PositionDelta = ToFlaxType(shapeControlPoints[i] - controlPoints[i]);
|
||||
// TODO: support importing normals from blend shape
|
||||
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
||||
blendShapeData.Vertices[i].NormalDelta = Vector3::Zero;
|
||||
blendShapeData.Vertices[i].NormalDelta = Float3::Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -730,7 +725,7 @@ bool ImportMeshes(ImporterData& data, String& errorMsg)
|
||||
}
|
||||
|
||||
/*
|
||||
void ImportCurve(aiVectorKey* keys, uint32 keysCount, LinearCurve<Vector3>& curve)
|
||||
void ImportCurve(aiVectorKey* keys, uint32 keysCount, LinearCurve<Float3>& curve)
|
||||
{
|
||||
if (keys == nullptr || keysCount == 0)
|
||||
return;
|
||||
@@ -743,7 +738,7 @@ void ImportCurve(aiVectorKey* keys, uint32 keysCount, LinearCurve<Vector3>& curv
|
||||
auto& key = keyframes[i];
|
||||
|
||||
key.Time = (float)aKey.mTime;
|
||||
key.Value = ToVector3(aKey.mValue);
|
||||
key.Value = ToFlaxType(aKey.mValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,19 +17,19 @@
|
||||
#include <ThirdParty/OpenFBX/ofbx.h>
|
||||
#include <memory>
|
||||
|
||||
Vector2 ToVector2(const ofbx::Vec2& v)
|
||||
Float2 ToFloat2(const ofbx::Vec2& v)
|
||||
{
|
||||
return Vector2((float)v.x, (float)v.y);
|
||||
return Float2((float)v.x, (float)v.y);
|
||||
}
|
||||
|
||||
Vector2 ToVector2(const ofbx::Vec3& v)
|
||||
Float2 ToFloat2(const ofbx::Vec3& v)
|
||||
{
|
||||
return Vector2((float)v.x, (float)v.y);
|
||||
return Float2((float)v.x, (float)v.y);
|
||||
}
|
||||
|
||||
Vector3 ToVector3(const ofbx::Vec3& v)
|
||||
Float3 ToFloat3(const ofbx::Vec3& v)
|
||||
{
|
||||
return Vector3((float)v.x, (float)v.y, (float)v.z);
|
||||
return Float3((float)v.x, (float)v.y, (float)v.z);
|
||||
}
|
||||
|
||||
Color ToColor(const ofbx::Vec4& v)
|
||||
@@ -85,9 +85,9 @@ struct OpenFbxImporterData
|
||||
const ModelTool::Options& Options;
|
||||
|
||||
ofbx::GlobalSettings GlobalSettings;
|
||||
Vector3 Up;
|
||||
Vector3 Front;
|
||||
Vector3 Right;
|
||||
Float3 Up;
|
||||
Float3 Front;
|
||||
Float3 Right;
|
||||
bool ConvertRH;
|
||||
float FrameRate;
|
||||
Quaternion RootConvertRotation = Quaternion::Identity;
|
||||
@@ -118,52 +118,52 @@ struct OpenFbxImporterData
|
||||
switch (GlobalSettings.UpAxis)
|
||||
{
|
||||
case ofbx::UpVector_AxisX:
|
||||
Up = Vector3((float)GlobalSettings.UpAxisSign, 0, 0);
|
||||
Up = Float3((float)GlobalSettings.UpAxisSign, 0, 0);
|
||||
switch (GlobalSettings.FrontAxis)
|
||||
{
|
||||
case ofbx::FrontVector_ParityEven:
|
||||
// Up: X, Front: Y, Right: Z
|
||||
Front = Vector3(0, (float)GlobalSettings.FrontAxisSign, 0);
|
||||
Right = Vector3(0, 0, coordAxisSign);
|
||||
Front = Float3(0, (float)GlobalSettings.FrontAxisSign, 0);
|
||||
Right = Float3(0, 0, coordAxisSign);
|
||||
break;
|
||||
case ofbx::FrontVector_ParityOdd:
|
||||
// Up: X, Front: Z, Right: Y
|
||||
Front = Vector3(0, 0, (float)GlobalSettings.FrontAxisSign);
|
||||
Right = Vector3(0, coordAxisSign, 0);
|
||||
Front = Float3(0, 0, (float)GlobalSettings.FrontAxisSign);
|
||||
Right = Float3(0, coordAxisSign, 0);
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
break;
|
||||
case ofbx::UpVector_AxisY:
|
||||
Up = Vector3(0, (float)GlobalSettings.UpAxisSign, 0);
|
||||
Up = Float3(0, (float)GlobalSettings.UpAxisSign, 0);
|
||||
switch (GlobalSettings.FrontAxis)
|
||||
{
|
||||
case ofbx::FrontVector_ParityEven:
|
||||
// Up: Y, Front: X, Right: Z
|
||||
Front = Vector3((float)GlobalSettings.FrontAxisSign, 0, 0);
|
||||
Right = Vector3(0, 0, coordAxisSign);
|
||||
Front = Float3((float)GlobalSettings.FrontAxisSign, 0, 0);
|
||||
Right = Float3(0, 0, coordAxisSign);
|
||||
break;
|
||||
case ofbx::FrontVector_ParityOdd:
|
||||
// Up: Y, Front: Z, Right: X
|
||||
Front = Vector3(0, 0, (float)GlobalSettings.FrontAxisSign);
|
||||
Right = Vector3(coordAxisSign, 0, 0);
|
||||
Front = Float3(0, 0, (float)GlobalSettings.FrontAxisSign);
|
||||
Right = Float3(coordAxisSign, 0, 0);
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
break;
|
||||
case ofbx::UpVector_AxisZ:
|
||||
Up = Vector3(0, 0, (float)GlobalSettings.UpAxisSign);
|
||||
Up = Float3(0, 0, (float)GlobalSettings.UpAxisSign);
|
||||
switch (GlobalSettings.FrontAxis)
|
||||
{
|
||||
case ofbx::FrontVector_ParityEven:
|
||||
// Up: Z, Front: X, Right: Y
|
||||
Front = Vector3((float)GlobalSettings.FrontAxisSign, 0, 0);
|
||||
Right = Vector3(0, coordAxisSign, 0);
|
||||
Front = Float3((float)GlobalSettings.FrontAxisSign, 0, 0);
|
||||
Right = Float3(0, coordAxisSign, 0);
|
||||
break;
|
||||
case ofbx::FrontVector_ParityOdd:
|
||||
// Up: Z, Front: Y, Right: X
|
||||
Front = Vector3((float)GlobalSettings.FrontAxisSign, 0, 0);
|
||||
Right = Vector3(coordAxisSign, 0, 0);
|
||||
Front = Float3((float)GlobalSettings.FrontAxisSign, 0, 0);
|
||||
Right = Float3(coordAxisSign, 0, 0);
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
@@ -491,7 +491,7 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb
|
||||
mesh.Positions.Resize(vertexCount, false);
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
mesh.Positions.Get()[i] = ToVector3(vertices[i + firstVertexOffset]);
|
||||
mesh.Positions.Get()[i] = ToFloat3(vertices[i + firstVertexOffset]);
|
||||
}
|
||||
|
||||
// Indices (dummy index buffer)
|
||||
@@ -512,7 +512,7 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb
|
||||
mesh.UVs.Resize(vertexCount, false);
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
mesh.UVs.Get()[i] = ToVector2(uvs[i + firstVertexOffset]);
|
||||
mesh.UVs.Get()[i] = ToFloat2(uvs[i + firstVertexOffset]);
|
||||
}
|
||||
if (data.ConvertRH)
|
||||
{
|
||||
@@ -537,7 +537,7 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb
|
||||
mesh.Normals.Resize(vertexCount, false);
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
mesh.Normals.Get()[i] = ToVector3(normals[i + firstVertexOffset]);
|
||||
mesh.Normals.Get()[i] = ToFloat3(normals[i + firstVertexOffset]);
|
||||
}
|
||||
if (data.ConvertRH)
|
||||
{
|
||||
@@ -559,7 +559,7 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb
|
||||
mesh.Tangents.Resize(vertexCount, false);
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
mesh.Tangents.Get()[i] = ToVector3(tangents[i + firstVertexOffset]);
|
||||
mesh.Tangents.Get()[i] = ToFloat3(tangents[i + firstVertexOffset]);
|
||||
}
|
||||
if (data.ConvertRH)
|
||||
{
|
||||
@@ -614,7 +614,7 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb
|
||||
mesh.LightmapUVs.Resize(vertexCount, false);
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
mesh.LightmapUVs.Get()[i] = ToVector2(lightmapUVs[i + firstVertexOffset]);
|
||||
mesh.LightmapUVs.Get()[i] = ToFloat2(lightmapUVs[i + firstVertexOffset]);
|
||||
}
|
||||
if (data.ConvertRH)
|
||||
{
|
||||
@@ -646,7 +646,7 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb
|
||||
mesh.BlendIndices.Resize(vertexCount);
|
||||
mesh.BlendWeights.Resize(vertexCount);
|
||||
mesh.BlendIndices.SetAll(Int4::Zero);
|
||||
mesh.BlendWeights.SetAll(Vector4::Zero);
|
||||
mesh.BlendWeights.SetAll(Float4::Zero);
|
||||
|
||||
for (int clusterIndex = 0, c = skin->getClusterCount(); clusterIndex < c; clusterIndex++)
|
||||
{
|
||||
@@ -737,18 +737,18 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb
|
||||
auto shapeVertices = shape->getVertices();
|
||||
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
||||
{
|
||||
auto delta = ToVector3(shapeVertices[i + firstVertexOffset]) - mesh.Positions.Get()[i];
|
||||
auto delta = ToFloat3(shapeVertices[i + firstVertexOffset]) - mesh.Positions.Get()[i];
|
||||
blendShapeData.Vertices.Get()[i].PositionDelta = delta;
|
||||
}
|
||||
|
||||
auto shapeNormals = shape->getNormals();
|
||||
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
|
||||
{
|
||||
/*auto delta = ToVector3(shapeNormals[i + firstVertexOffset]) - mesh.Normals[i];
|
||||
/*auto delta = ToFloat3(shapeNormals[i + firstVertexOffset]) - mesh.Normals[i];
|
||||
auto length = delta.Length();
|
||||
if (length > ZeroTolerance)
|
||||
delta /= length;*/
|
||||
auto delta = Vector3::Zero; // TODO: blend shape normals deltas fix when importing from fbx
|
||||
auto delta = Float3::Zero; // TODO: blend shape normals deltas fix when importing from fbx
|
||||
blendShapeData.Vertices.Get()[i].NormalDelta = delta;
|
||||
}
|
||||
}
|
||||
@@ -917,7 +917,7 @@ struct Frame
|
||||
ofbx::Vec3 Scaling;
|
||||
};
|
||||
|
||||
void ExtractKeyframePosition(const ofbx::Object* bone, ofbx::Vec3& trans, const Frame& localFrame, Vector3& keyframe)
|
||||
void ExtractKeyframePosition(const ofbx::Object* bone, ofbx::Vec3& trans, const Frame& localFrame, Float3& keyframe)
|
||||
{
|
||||
const Matrix frameTrans = ToMatrix(bone->evalLocal(trans, localFrame.Rotation, localFrame.Scaling));
|
||||
keyframe = frameTrans.GetTranslation();
|
||||
@@ -929,7 +929,7 @@ void ExtractKeyframeRotation(const ofbx::Object* bone, ofbx::Vec3& trans, const
|
||||
Quaternion::RotationMatrix(frameTrans, keyframe);
|
||||
}
|
||||
|
||||
void ExtractKeyframeScale(const ofbx::Object* bone, ofbx::Vec3& trans, const Frame& localFrame, Vector3& keyframe)
|
||||
void ExtractKeyframeScale(const ofbx::Object* bone, ofbx::Vec3& trans, const Frame& localFrame, Float3& keyframe)
|
||||
{
|
||||
// Fix empty scale case
|
||||
if (Math::IsZero(trans.x) && Math::IsZero(trans.y) && Math::IsZero(trans.z))
|
||||
@@ -1045,7 +1045,7 @@ bool ImportAnimation(int32 index, ImportedModelData& data, OpenFbxImporterData&
|
||||
return false;
|
||||
}
|
||||
|
||||
static Vector3 FbxVectorFromAxisAndSign(int axis, int sign)
|
||||
static Float3 FbxVectorFromAxisAndSign(int axis, int sign)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
@@ -1131,20 +1131,20 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt
|
||||
}
|
||||
|
||||
// Transform nodes to match the engine coordinates system - DirectX (UpVector = +Y, FrontVector = +Z, CoordSystem = -X (LeftHanded))
|
||||
if (context->Up == Vector3(1, 0, 0) && context->Front == Vector3(0, 0, 1) && context->Right == Vector3(0, 1, 0))
|
||||
if (context->Up == Float3(1, 0, 0) && context->Front == Float3(0, 0, 1) && context->Right == Float3(0, 1, 0))
|
||||
{
|
||||
context->RootConvertRotation = Quaternion::Euler(0, 180, 0);
|
||||
}
|
||||
else if (context->Up == Vector3(0, 1, 0) && context->Front == Vector3(-1, 0, 0) && context->Right == Vector3(0, 0, 1))
|
||||
else if (context->Up == Float3(0, 1, 0) && context->Front == Float3(-1, 0, 0) && context->Right == Float3(0, 0, 1))
|
||||
{
|
||||
context->RootConvertRotation = Quaternion::Euler(90, -90, 0);
|
||||
}
|
||||
/*Vector3 engineUp(0, 1, 0);
|
||||
Vector3 engineFront(0, 0, 1);
|
||||
Vector3 engineRight(-1, 0, 0);*/
|
||||
/*Vector3 engineUp(1, 0, 0);
|
||||
Vector3 engineFront(0, 0, 1);
|
||||
Vector3 engineRight(0, 1, 0);
|
||||
/*Float3 engineUp(0, 1, 0);
|
||||
Float3 engineFront(0, 0, 1);
|
||||
Float3 engineRight(-1, 0, 0);*/
|
||||
/*Float3 engineUp(1, 0, 0);
|
||||
Float3 engineFront(0, 0, 1);
|
||||
Float3 engineRight(0, 1, 0);
|
||||
if (context->Up != engineUp || context->Front != engineFront || context->Right != engineRight)
|
||||
{
|
||||
LOG(Info, "Converting imported scene nodes to match engine coordinates system");
|
||||
@@ -1152,10 +1152,10 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt
|
||||
//context->RootConvertRotation *= Quaternion::GetRotationFromTo(rotation * context->Right, engineRight, engineRight);
|
||||
//context->RootConvertRotation *= Quaternion::GetRotationFromTo(rotation * context->Front, engineFront, engineFront);
|
||||
}*/
|
||||
/*Vector3 hackUp = FbxVectorFromAxisAndSign(globalSettings.UpAxis, globalSettings.UpAxisSign);
|
||||
if (hackUp == Vector3::UnitX)
|
||||
/*Float3 hackUp = FbxVectorFromAxisAndSign(globalSettings.UpAxis, globalSettings.UpAxisSign);
|
||||
if (hackUp == Float3::UnitX)
|
||||
context->RootConvertRotation = Quaternion::Euler(-90, 0, 0);
|
||||
else if (hackUp == Vector3::UnitZ)
|
||||
else if (hackUp == Float3::UnitZ)
|
||||
context->RootConvertRotation = Quaternion::Euler(90, 0, 0);*/
|
||||
if (!context->RootConvertRotation.IsIdentity())
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "MeshAccelerationStructure.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/RandomStream.h"
|
||||
#include "Engine/Core/Math/Int3.h"
|
||||
#include "Engine/Core/Math/Vector3.h"
|
||||
#include "Engine/Core/Math/Ray.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Threading/JobSystem.h"
|
||||
@@ -79,13 +79,13 @@ bool ModelTool::GenerateModelSDF(Model* inputModel, ModelData* modelData, float
|
||||
bounds = modelData->LODs[lodIndex].GetBox();
|
||||
else
|
||||
return true;
|
||||
Vector3 size = bounds.GetSize();
|
||||
Float3 size = bounds.GetSize();
|
||||
ModelBase::SDFData sdf;
|
||||
sdf.WorldUnitsPerVoxel = 10 / Math::Max(resolutionScale, 0.0001f);
|
||||
Int3 resolution(Vector3::Ceil(Vector3::Clamp(size / sdf.WorldUnitsPerVoxel, 4, 256)));
|
||||
Vector3 uvwToLocalMul = size;
|
||||
Vector3 uvwToLocalAdd = bounds.Minimum;
|
||||
sdf.LocalToUVWMul = Vector3::One / uvwToLocalMul;
|
||||
Int3 resolution(Float3::Ceil(Float3::Clamp(size / sdf.WorldUnitsPerVoxel, 4, 256)));
|
||||
Float3 uvwToLocalMul = size;
|
||||
Float3 uvwToLocalAdd = bounds.Minimum;
|
||||
sdf.LocalToUVWMul = Float3::One / uvwToLocalMul;
|
||||
sdf.LocalToUVWAdd = -uvwToLocalAdd / uvwToLocalMul;
|
||||
sdf.MaxDistance = size.MaxValue();
|
||||
sdf.LocalBoundsMin = bounds.Minimum;
|
||||
@@ -149,10 +149,10 @@ bool ModelTool::GenerateModelSDF(Model* inputModel, ModelData* modelData, float
|
||||
// Allocate memory for the distant field
|
||||
const int32 voxelsSize = resolution.X * resolution.Y * resolution.Z * formatStride;
|
||||
void* voxels = Allocator::Allocate(voxelsSize);
|
||||
Vector3 xyzToLocalMul = uvwToLocalMul / Vector3(resolution);
|
||||
Vector3 xyzToLocalAdd = uvwToLocalAdd;
|
||||
const Vector2 encodeMAD(0.5f / sdf.MaxDistance * formatMaxValue, 0.5f * formatMaxValue);
|
||||
const Vector2 decodeMAD(2.0f * sdf.MaxDistance / formatMaxValue, -sdf.MaxDistance);
|
||||
Float3 xyzToLocalMul = uvwToLocalMul / Float3(resolution);
|
||||
Float3 xyzToLocalAdd = uvwToLocalAdd;
|
||||
const Float2 encodeMAD(0.5f / sdf.MaxDistance * formatMaxValue, 0.5f * formatMaxValue);
|
||||
const Float2 decodeMAD(2.0f * sdf.MaxDistance / formatMaxValue, -sdf.MaxDistance);
|
||||
int32 voxelSizeSum = voxelsSize;
|
||||
|
||||
// TODO: use optimized sparse storage for SDF data as hierarchical bricks as in papers below:
|
||||
@@ -163,23 +163,23 @@ bool ModelTool::GenerateModelSDF(Model* inputModel, ModelData* modelData, float
|
||||
|
||||
// Brute-force for each voxel to calculate distance to the closest triangle with point query and distance sign by raycasting around the voxel
|
||||
const int32 sampleCount = 12;
|
||||
Array<Vector3> sampleDirections;
|
||||
Array<Float3> sampleDirections;
|
||||
sampleDirections.Resize(sampleCount);
|
||||
{
|
||||
RandomStream rand;
|
||||
sampleDirections.Get()[0] = Vector3::Up;
|
||||
sampleDirections.Get()[1] = Vector3::Down;
|
||||
sampleDirections.Get()[2] = Vector3::Left;
|
||||
sampleDirections.Get()[3] = Vector3::Right;
|
||||
sampleDirections.Get()[4] = Vector3::Forward;
|
||||
sampleDirections.Get()[5] = Vector3::Backward;
|
||||
sampleDirections.Get()[0] = Float3::Up;
|
||||
sampleDirections.Get()[1] = Float3::Down;
|
||||
sampleDirections.Get()[2] = Float3::Left;
|
||||
sampleDirections.Get()[3] = Float3::Right;
|
||||
sampleDirections.Get()[4] = Float3::Forward;
|
||||
sampleDirections.Get()[5] = Float3::Backward;
|
||||
for (int32 i = 6; i < sampleCount; i++)
|
||||
sampleDirections.Get()[i] = rand.GetUnitVector();
|
||||
}
|
||||
Function<void(int32)> sdfJob = [&sdf, &resolution, &backfacesThreshold, &sampleDirections, &scene, &voxels, &xyzToLocalMul, &xyzToLocalAdd, &encodeMAD, &formatStride, &formatWrite](int32 z)
|
||||
{
|
||||
PROFILE_CPU_NAMED("Model SDF Job");
|
||||
float hitDistance;
|
||||
Real hitDistance;
|
||||
Vector3 hitNormal, hitPoint;
|
||||
Triangle hitTriangle;
|
||||
const int32 zAddress = resolution.Y * resolution.X * z;
|
||||
@@ -188,8 +188,8 @@ bool ModelTool::GenerateModelSDF(Model* inputModel, ModelData* modelData, float
|
||||
const int32 yAddress = resolution.X * y + zAddress;
|
||||
for (int32 x = 0; x < resolution.X; x++)
|
||||
{
|
||||
float minDistance = sdf.MaxDistance;
|
||||
Vector3 voxelPos = Vector3((float)x, (float)y, (float)z) * xyzToLocalMul + xyzToLocalAdd;
|
||||
Real minDistance = sdf.MaxDistance;
|
||||
Vector3 voxelPos = Float3((float)x, (float)y, (float)z) * xyzToLocalMul + xyzToLocalAdd;
|
||||
|
||||
// Point query to find the distance to the closest surface
|
||||
scene.PointQuery(voxelPos, minDistance, hitPoint, hitTriangle);
|
||||
@@ -202,13 +202,13 @@ bool ModelTool::GenerateModelSDF(Model* inputModel, ModelData* modelData, float
|
||||
if (scene.RayCast(sampleRay, hitDistance, hitNormal, hitTriangle))
|
||||
{
|
||||
hitCount++;
|
||||
const bool backHit = Vector3::Dot(sampleRay.Direction, hitTriangle.GetNormal()) > 0;
|
||||
const bool backHit = Float3::Dot(sampleRay.Direction, hitTriangle.GetNormal()) > 0;
|
||||
if (backHit)
|
||||
hitBackCount++;
|
||||
}
|
||||
}
|
||||
|
||||
float distance = minDistance;
|
||||
float distance = (float)minDistance;
|
||||
// TODO: surface thickness threshold? shift reduce distance for all voxels by something like 0.01 to enlarge thin geometry
|
||||
// if ((float)hitBackCount > (float)hitCount * 0.3f && hitCount != 0)
|
||||
if ((float)hitBackCount > (float)sampleDirections.Count() * backfacesThreshold && hitCount != 0)
|
||||
@@ -724,7 +724,7 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
|
||||
LOG(Warning, "Imported mesh \'{0}\' has missing skinning data. It may result in invalid rendering.", mesh->Name);
|
||||
|
||||
auto indices = Int4::Zero;
|
||||
auto weights = Vector4::UnitX;
|
||||
auto weights = Float4::UnitX;
|
||||
|
||||
// Check if use a single bone for skinning
|
||||
auto nodeIndex = data.Skeleton.FindNode(mesh->Name);
|
||||
@@ -876,7 +876,7 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
|
||||
}
|
||||
|
||||
// Prepare import transformation
|
||||
Transform importTransform(options.Translation, options.Rotation, Vector3(options.Scale));
|
||||
Transform importTransform(options.Translation, options.Rotation, Float3(options.Scale));
|
||||
if (options.CenterGeometry && data.LODs.HasItems() && data.LODs[0].Meshes.HasItems())
|
||||
{
|
||||
// Calculate the bounding box (use LOD0 as a reference)
|
||||
@@ -1031,8 +1031,8 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
|
||||
const float atlasSizeInv = 1.0f / atlasSize;
|
||||
for (const auto& entry : entries)
|
||||
{
|
||||
Vector2 uvOffset(entry.Slot->X * atlasSizeInv, entry.Slot->Y * atlasSizeInv);
|
||||
Vector2 uvScale((entry.Slot->Width - chartsPadding) * atlasSizeInv, (entry.Slot->Height - chartsPadding) * atlasSizeInv);
|
||||
Float2 uvOffset(entry.Slot->X * atlasSizeInv, entry.Slot->Y * atlasSizeInv);
|
||||
Float2 uvScale((entry.Slot->Width - chartsPadding) * atlasSizeInv, (entry.Slot->Height - chartsPadding) * atlasSizeInv);
|
||||
// TODO: SIMD
|
||||
for (auto& uv : entry.Mesh->LightmapUVs)
|
||||
{
|
||||
@@ -1407,7 +1407,7 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
|
||||
int32 dstMeshIndexCountTarget = int32(srcMeshIndexCount * triangleReduction) / 3 * 3;
|
||||
Array<unsigned int> indices;
|
||||
indices.Resize(dstMeshIndexCountTarget);
|
||||
int32 dstMeshIndexCount = (int32)meshopt_simplifySloppy(indices.Get(), srcMesh->Indices.Get(), srcMeshIndexCount, (const float*)srcMesh->Positions.Get(), srcMeshVertexCount, sizeof(Vector3), dstMeshIndexCountTarget);
|
||||
int32 dstMeshIndexCount = (int32)meshopt_simplifySloppy(indices.Get(), srcMesh->Indices.Get(), srcMeshIndexCount, (const float*)srcMesh->Positions.Get(), srcMeshVertexCount, sizeof(Float3), dstMeshIndexCountTarget);
|
||||
indices.Resize(dstMeshIndexCount);
|
||||
if (dstMeshIndexCount == 0)
|
||||
continue;
|
||||
@@ -1429,15 +1429,15 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
|
||||
dstMesh->name.Resize(dstMeshVertexCount); \
|
||||
meshopt_remapVertexBuffer(dstMesh->name.Get(), srcMesh->name.Get(), srcMeshVertexCount, sizeof(type), remap.Get()); \
|
||||
}
|
||||
REMAP_VERTEX_BUFFER(Positions, Vector3);
|
||||
REMAP_VERTEX_BUFFER(UVs, Vector2);
|
||||
REMAP_VERTEX_BUFFER(Normals, Vector3);
|
||||
REMAP_VERTEX_BUFFER(Tangents, Vector3);
|
||||
REMAP_VERTEX_BUFFER(Tangents, Vector3);
|
||||
REMAP_VERTEX_BUFFER(LightmapUVs, Vector2);
|
||||
REMAP_VERTEX_BUFFER(Positions, Float3);
|
||||
REMAP_VERTEX_BUFFER(UVs, Float2);
|
||||
REMAP_VERTEX_BUFFER(Normals, Float3);
|
||||
REMAP_VERTEX_BUFFER(Tangents, Float3);
|
||||
REMAP_VERTEX_BUFFER(Tangents, Float3);
|
||||
REMAP_VERTEX_BUFFER(LightmapUVs, Float2);
|
||||
REMAP_VERTEX_BUFFER(Colors, Color);
|
||||
REMAP_VERTEX_BUFFER(BlendIndices, Int4);
|
||||
REMAP_VERTEX_BUFFER(BlendWeights, Vector4);
|
||||
REMAP_VERTEX_BUFFER(BlendWeights, Float4);
|
||||
#undef REMAP_VERTEX_BUFFER
|
||||
|
||||
// Remap blend shapes
|
||||
@@ -1470,7 +1470,7 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
|
||||
|
||||
// Optimize generated LOD
|
||||
meshopt_optimizeVertexCache(dstMesh->Indices.Get(), dstMesh->Indices.Get(), dstMeshIndexCount, dstMeshVertexCount);
|
||||
meshopt_optimizeOverdraw(dstMesh->Indices.Get(), dstMesh->Indices.Get(), dstMeshIndexCount, (const float*)dstMesh->Positions.Get(), dstMeshVertexCount, sizeof(Vector3), 1.05f);
|
||||
meshopt_optimizeOverdraw(dstMesh->Indices.Get(), dstMesh->Indices.Get(), dstMeshIndexCount, (const float*)dstMesh->Positions.Get(), dstMeshVertexCount, sizeof(Float3), 1.05f);
|
||||
|
||||
lodTriangleCount += dstMeshIndexCount / 3;
|
||||
lodVertexCount += dstMeshVertexCount;
|
||||
|
||||
@@ -147,13 +147,13 @@ public:
|
||||
|
||||
struct ModelSDFHeader
|
||||
{
|
||||
Vector3 LocalToUVWMul;
|
||||
Float3 LocalToUVWMul;
|
||||
float WorldUnitsPerVoxel;
|
||||
Vector3 LocalToUVWAdd;
|
||||
Float3 LocalToUVWAdd;
|
||||
float MaxDistance;
|
||||
Vector3 LocalBoundsMin;
|
||||
Float3 LocalBoundsMin;
|
||||
int32 MipLevels;
|
||||
Vector3 LocalBoundsMax;
|
||||
Float3 LocalBoundsMax;
|
||||
int32 Width;
|
||||
int32 Height;
|
||||
int32 Depth;
|
||||
@@ -228,7 +228,7 @@ public:
|
||||
|
||||
// Animation
|
||||
AnimationDuration Duration = AnimationDuration::Imported;
|
||||
Vector2 FramesRange = Vector2::Zero;
|
||||
Float2 FramesRange = Float2::Zero;
|
||||
float DefaultFrameRate = 0.0f;
|
||||
float SamplingRate = 0.0f;
|
||||
bool SkipEmptyCurves = true;
|
||||
|
||||
Reference in New Issue
Block a user