Refactor engine to support double-precision vectors
This commit is contained in:
@@ -18,8 +18,8 @@ namespace CSG
|
||||
struct Surface : Plane
|
||||
{
|
||||
Guid Material;
|
||||
Vector2 TexCoordScale;
|
||||
Vector2 TexCoordOffset;
|
||||
Float2 TexCoordScale;
|
||||
Float2 TexCoordOffset;
|
||||
float TexCoordRotation;
|
||||
float ScaleInLightmap;
|
||||
|
||||
@@ -79,12 +79,11 @@ namespace CSG
|
||||
|
||||
public:
|
||||
|
||||
static Vector3 Intersection(const Vector3& start, const Vector3& end, float sdist, float edist)
|
||||
static Vector3 Intersection(const Vector3& start, const Vector3& end, Real sdist, Real edist)
|
||||
{
|
||||
Vector3 vector = end - start;
|
||||
float length = edist - sdist;
|
||||
float delta = edist / length;
|
||||
|
||||
Real length = edist - sdist;
|
||||
Real delta = edist / length;
|
||||
return end - (delta * vector);
|
||||
}
|
||||
|
||||
@@ -93,18 +92,7 @@ namespace CSG
|
||||
return Intersection(start, end, Distance(start), Distance(end));
|
||||
}
|
||||
|
||||
float Distance(float x, float y, float z) const
|
||||
{
|
||||
return
|
||||
(
|
||||
(Normal.X * x) +
|
||||
(Normal.Y * y) +
|
||||
(Normal.Z * z) -
|
||||
(D)
|
||||
);
|
||||
}
|
||||
|
||||
float Distance(const Vector3& vertex) const
|
||||
Real Distance(const Vector3& vertex) const
|
||||
{
|
||||
return
|
||||
(
|
||||
@@ -115,7 +103,7 @@ namespace CSG
|
||||
);
|
||||
}
|
||||
|
||||
static PlaneIntersectionType OnSide(float distance)
|
||||
static PlaneIntersectionType OnSide(Real distance)
|
||||
{
|
||||
if (distance > DistanceEpsilon)
|
||||
return PlaneIntersectionType::Front;
|
||||
@@ -124,11 +112,6 @@ namespace CSG
|
||||
return PlaneIntersectionType::Intersecting;
|
||||
}
|
||||
|
||||
PlaneIntersectionType OnSide(float x, float y, float z) const
|
||||
{
|
||||
return OnSide(Distance(x, y, z));
|
||||
}
|
||||
|
||||
PlaneIntersectionType OnSide(const Vector3& vertex) const
|
||||
{
|
||||
return OnSide(Distance(vertex));
|
||||
@@ -139,24 +122,20 @@ namespace CSG
|
||||
Vector3 min;
|
||||
Vector3 max;
|
||||
|
||||
max.X = static_cast<float>((Normal.X >= 0.0f) ? box.MinX : box.MaxX);
|
||||
max.Y = static_cast<float>((Normal.Y >= 0.0f) ? box.MinY : box.MaxY);
|
||||
max.Z = static_cast<float>((Normal.Z >= 0.0f) ? box.MinZ : box.MaxZ);
|
||||
max.X = static_cast<Real>((Normal.X >= 0.0f) ? box.MinX : box.MaxX);
|
||||
max.Y = static_cast<Real>((Normal.Y >= 0.0f) ? box.MinY : box.MaxY);
|
||||
max.Z = static_cast<Real>((Normal.Z >= 0.0f) ? box.MinZ : box.MaxZ);
|
||||
|
||||
min.X = static_cast<float>((Normal.X >= 0.0f) ? box.MaxX : box.MinX);
|
||||
min.Y = static_cast<float>((Normal.Y >= 0.0f) ? box.MaxY : box.MinY);
|
||||
min.Z = static_cast<float>((Normal.Z >= 0.0f) ? box.MaxZ : box.MinZ);
|
||||
|
||||
float distance = Vector3::Dot(Normal, max) - D;
|
||||
min.X = static_cast<Real>((Normal.X >= 0.0f) ? box.MaxX : box.MinX);
|
||||
min.Y = static_cast<Real>((Normal.Y >= 0.0f) ? box.MaxY : box.MinY);
|
||||
min.Z = static_cast<Real>((Normal.Z >= 0.0f) ? box.MaxZ : box.MinZ);
|
||||
|
||||
Real distance = Vector3::Dot(Normal, max) - D;
|
||||
if (distance > DistanceEpsilon)
|
||||
return PlaneIntersectionType::Front;
|
||||
|
||||
distance = Vector3::Dot(Normal, min) - D;
|
||||
|
||||
if (distance < -DistanceEpsilon)
|
||||
return PlaneIntersectionType::Back;
|
||||
|
||||
return PlaneIntersectionType::Intersecting;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -334,9 +334,9 @@ bool CSGBuilderImpl::buildInner(Scene* scene, BuildData& data)
|
||||
auto lod = &modelData.LODs[lodIndex];
|
||||
for (int32 meshIndex = 0; meshIndex < lod->Meshes.Count(); meshIndex++)
|
||||
{
|
||||
const auto v = &lod->Meshes[meshIndex]->Positions;
|
||||
for (int32 i = 0; i < v->Count(); i++)
|
||||
Vector3::Transform(v->Get()[i], m2, v->Get()[i]);
|
||||
Array<Float3>& v = lod->Meshes[meshIndex]->Positions;
|
||||
for (int32 i = 0; i < v.Count(); i++)
|
||||
Float3::Transform(v[i], m2, v[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -411,7 +411,7 @@ bool CSGBuilderImpl::generateRawDataAsset(Scene* scene, RawData& meshData, Guid&
|
||||
int32 brushDataSize = 0;
|
||||
for (int32 i = 0; i < surfaces.Count(); i++)
|
||||
{
|
||||
brushDataSize += sizeof(int32) + sizeof(Triangle) * surfaces[i].Triangles.Count();
|
||||
brushDataSize += sizeof(int32) + sizeof(RawData::SurfaceTriangle) * surfaces[i].Triangles.Count();
|
||||
}
|
||||
surfacesDataOffset += brushDataSize;
|
||||
}
|
||||
|
||||
@@ -88,9 +88,9 @@ void RawData::AddSurface(Brush* brush, int32 brushSurfaceIndex, const Guid& surf
|
||||
for (int32 i = 0; i < vertexCount;)
|
||||
{
|
||||
auto& triangle = triangles[i / 3];
|
||||
triangle.V0 = firstVertex[i++].Position;
|
||||
triangle.V1 = firstVertex[i++].Position;
|
||||
triangle.V2 = firstVertex[i++].Position;
|
||||
triangle.V[0] = firstVertex[i++].Position;
|
||||
triangle.V[1] = firstVertex[i++].Position;
|
||||
triangle.V[2] = firstVertex[i++].Position;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,19 +22,23 @@ namespace CSG
|
||||
class RawData
|
||||
{
|
||||
public:
|
||||
|
||||
struct Surface
|
||||
{
|
||||
float ScaleInLightmap;
|
||||
Rectangle LightmapUVsBox;
|
||||
Vector2 Size;
|
||||
Float2 Size;
|
||||
Rectangle UVsArea;
|
||||
Array<RawModelVertex> Vertices;
|
||||
};
|
||||
|
||||
struct SurfaceTriangle
|
||||
{
|
||||
Float3 V[3];
|
||||
};
|
||||
|
||||
struct SurfaceData
|
||||
{
|
||||
Array<Triangle> Triangles;
|
||||
Array<SurfaceTriangle> Triangles;
|
||||
};
|
||||
|
||||
struct BrushData
|
||||
@@ -45,12 +49,10 @@ namespace CSG
|
||||
class Slot
|
||||
{
|
||||
public:
|
||||
|
||||
Guid Material;
|
||||
Array<Surface> Surfaces;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Slot"/> class.
|
||||
/// </summary>
|
||||
@@ -61,7 +63,6 @@ namespace CSG
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return Surfaces.IsEmpty();
|
||||
@@ -71,7 +72,6 @@ namespace CSG
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The slots.
|
||||
/// </summary>
|
||||
@@ -83,7 +83,6 @@ namespace CSG
|
||||
Dictionary<Guid, BrushData> Brushes;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RawData"/> class.
|
||||
/// </summary>
|
||||
@@ -100,7 +99,6 @@ namespace CSG
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets or adds the slot for the given material.
|
||||
/// </summary>
|
||||
@@ -120,7 +118,6 @@ namespace CSG
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void AddSurface(Brush* brush, int32 brushSurfaceIndex, const Guid& surfaceMaterial, float scaleInLightmap, const Rectangle& lightmapUVsBox, const RawModelVertex* firstVertex, int32 vertexCount);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -87,45 +87,44 @@ bool CSG::Mesh::Triangulate(RawData& data, Array<RawModelVertex>& cacheVB) const
|
||||
Vector3 v0 = _vertices[triangleIndices[0]];
|
||||
Vector3 v1 = _vertices[triangleIndices[1]];
|
||||
Vector3 v2 = _vertices[triangleIndices[2]];
|
||||
Vector3 vd0 = v1 - v0;
|
||||
Vector3 vd1 = v2 - v0;
|
||||
Vector3 normal = Vector3::Normalize(vd0 ^ vd1);
|
||||
Float3 vd0 = v1 - v0;
|
||||
Float3 vd1 = v2 - v0;
|
||||
Float3 normal = Float3::Normalize(vd0 ^ vd1);
|
||||
|
||||
// Calculate texture uvs based on vertex position
|
||||
for (int32 q = 0; q < 3; q++)
|
||||
{
|
||||
Vector3 pos = _vertices[triangleIndices[q]];
|
||||
Vector3::Transform(pos, finalTrans, uvPos);
|
||||
|
||||
Vector2 texCoord = Vector2(uvPos.X - centerPos.X, uvPos.Z - centerPos.Z);
|
||||
Float2 texCoord = Vector2(uvPos.X - centerPos.X, uvPos.Z - centerPos.Z);
|
||||
|
||||
// Apply surface uvs transformation
|
||||
uvs[q] = (texCoord * (surface.TexCoordScale * CSG_MESH_UV_SCALE)) + surface.TexCoordOffset;
|
||||
}
|
||||
|
||||
// Calculate tangent (it needs uvs)
|
||||
Vector2 uvd0 = uvs[1] - uvs[0];
|
||||
Vector2 uvd1 = uvs[2] - uvs[0];
|
||||
Float2 uvd0 = uvs[1] - uvs[0];
|
||||
Float2 uvd1 = uvs[2] - uvs[0];
|
||||
float dR = (uvd0.X * uvd1.Y - uvd1.X * uvd0.Y);
|
||||
if (Math::IsZero(dR))
|
||||
dR = 1.0f;
|
||||
float r = 1.0f / dR;
|
||||
Vector3 tangent = (vd0 * uvd1.Y - vd1 * uvd0.Y) * r;
|
||||
Vector3 bitangent = (vd1 * uvd0.X - vd0 * uvd1.X) * r;
|
||||
Float3 tangent = (vd0 * uvd1.Y - vd1 * uvd0.Y) * r;
|
||||
Float3 bitangent = (vd1 * uvd0.X - vd0 * uvd1.X) * r;
|
||||
tangent.Normalize();
|
||||
|
||||
// Gram-Schmidt orthogonalize
|
||||
Vector3 newTangentUnnormalized = tangent - normal * Vector3::Dot(normal, tangent);
|
||||
Float3 newTangentUnnormalized = tangent - normal * Float3::Dot(normal, tangent);
|
||||
const float length = newTangentUnnormalized.Length();
|
||||
|
||||
// Workaround to handle degenerated case
|
||||
if (Math::IsZero(length))
|
||||
{
|
||||
tangent = Vector3::Cross(normal, Vector3::UnitX);
|
||||
tangent = Float3::Cross(normal, Float3::UnitX);
|
||||
if (Math::IsZero(tangent.Length()))
|
||||
tangent = Vector3::Cross(normal, Vector3::UnitY);
|
||||
tangent = Float3::Cross(normal, Float3::UnitY);
|
||||
tangent.Normalize();
|
||||
bitangent = Vector3::Cross(normal, tangent);
|
||||
bitangent = Float3::Cross(normal, tangent);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -186,8 +185,8 @@ bool CSG::Mesh::Triangulate(RawData& data, Array<RawModelVertex>& cacheVB) const
|
||||
int32 brushSurfaceIndex = surfaceIndex - brushMeta.StartSurfaceIndex;
|
||||
int32 triangleCount = iPerSurface->Value.Count();
|
||||
int32 vertexCount = triangleCount * 3;
|
||||
Vector2 lightmapUVsMin = Vector2::Maximum;
|
||||
Vector2 lightmapUVsMax = Vector2::Minimum;
|
||||
Float2 lightmapUVsMin = Float2::Maximum;
|
||||
Float2 lightmapUVsMax = Float2::Minimum;
|
||||
const Surface& surface = _surfaces[surfaceIndex];
|
||||
|
||||
// Generate lightmap uvs per brush surface
|
||||
@@ -227,7 +226,7 @@ bool CSG::Mesh::Triangulate(RawData& data, Array<RawModelVertex>& cacheVB) const
|
||||
}
|
||||
|
||||
// Normalize projected positions to get lightmap uvs
|
||||
float projectedSize = (max - min).MaxValue();
|
||||
Real projectedSize = (max - min).MaxValue();
|
||||
for (int32 triangleIndex = 0; triangleIndex < triangleCount; triangleIndex++)
|
||||
{
|
||||
int32 triangleStartVertex = iPerSurface->Value[triangleIndex];
|
||||
@@ -237,8 +236,8 @@ bool CSG::Mesh::Triangulate(RawData& data, Array<RawModelVertex>& cacheVB) const
|
||||
|
||||
vertex.LightmapUVs = (pointsCache[triangleIndex * 3 + k] - min) / projectedSize;
|
||||
|
||||
lightmapUVsMin = Vector2::Min(lightmapUVsMin, vertex.LightmapUVs);
|
||||
lightmapUVsMax = Vector2::Max(lightmapUVsMax, vertex.LightmapUVs);
|
||||
lightmapUVsMin = Float2::Min(lightmapUVsMin, vertex.LightmapUVs);
|
||||
lightmapUVsMax = Float2::Max(lightmapUVsMax, vertex.LightmapUVs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user