Refactor engine to support double-precision vectors

This commit is contained in:
Wojtek Figat
2022-06-13 00:40:32 +02:00
parent f82e370392
commit a881c90b2e
744 changed files with 19062 additions and 12467 deletions

View File

@@ -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;
}
};

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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);
}
}
}