-
-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[50$ Bounty] Create RealtimeCSG Brush from PolygonMesh #3
Labels
Comments
This is a functional prototype / proof of concept of Bounty.cs written by me. But it's not perfect, it will fail when the front or back scale of a "scaled extrude" is zero (a pyramid shape). It's also pretty hacky with LINQ. using AeternumGames.ShapeEditor;
using InternalRealtimeCSG;
using RealtimeCSG.Components;
using RealtimeCSG.Legacy;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Shape = RealtimeCSG.Legacy.Shape;
namespace RealtimeCSG
{
public static class Bounty
{
public static CSGBrush CreateBrushFromPolygonMesh(Transform parent, string brushName, PolygonMesh mesh)
{
foreach (var polygon in mesh)
{
polygon.Reverse();
}
var controlMesh = new ControlMesh();
//// control mesh polygons:
int edgeIndex = 0;
controlMesh.Polygons = new Legacy.Polygon[mesh.Count];
for (int i = 0; i < mesh.Count; i++)
{
controlMesh.Polygons[i] = new Legacy.Polygon(new int[mesh[i].Count], i);
for (int j = 0; j < mesh[i].Count; j++)
{
controlMesh.Polygons[i].EdgeIndices[j] = edgeIndex;
edgeIndex++;
}
}
//// control mesh vertices:
var vertices = new List<Vector3>();
foreach (var polygon in mesh)
{
foreach (var vertex in polygon)
{
vertices.Add(vertex.position);
}
}
controlMesh.Vertices = vertices.Distinct().ToArray();
//// control mesh half edges:
var edges = new List<HalfEdge>();
for (short i = 0; i < mesh.Count; i++)
{
var polygon = mesh[i];
for (int j = 0; j < polygon.Count; j++)
{
var vertex = polygon[j];
var vertexIndex = (short)vertices.FindIndex(v => v.EqualsWithEpsilon5(vertex.position));
edges.Add(new HalfEdge { PolygonIndex = i, VertexIndex = vertexIndex, TwinIndex = -1 });
}
}
controlMesh.Edges = edges.ToArray();
//// control mesh half edge twin association:
var twn = 0;
for (short i = 0; i < mesh.Count; i++)
{
var polygon = mesh[i];
for (int j = 0; j < polygon.Count; j++)
{
var previous = polygon.PreviousVertex(j);
var current = polygon[j];
var cnt = 0;
for (short z = 0; z < mesh.Count; z++)
{
var polygon2 = mesh[z];
for (int k = 0; k < polygon2.Count; k++)
{
cnt++;
if (i == z) continue;
var previous2 = polygon2.PreviousVertex(k);
var current2 = polygon2[k];
if (previous2.position.EqualsWithEpsilon5(current.position) && current2.position.EqualsWithEpsilon5(previous.position))
{
controlMesh.Edges[twn].TwinIndex = cnt - 1;
}
}
}
twn++;
}
}
//// shape:
var shape = new Shape();
var material = CSGSettings.DefaultMaterial;
var polygonCount = mesh.Count;
shape.Surfaces = new Surface[polygonCount];
shape.TexGens = new TexGen[polygonCount];
shape.TexGenFlags = new TexGenFlags[polygonCount];
for (int i = 0; i < polygonCount; i++)
{
shape.Surfaces[i].TexGenIndex = i;
shape.Surfaces[i].Plane = GeometryUtility.CalcPolygonPlane(controlMesh, (short)i);
GeometryUtility.CalculateTangents(shape.Surfaces[i].Plane.normal, out shape.Surfaces[i].Tangent, out shape.Surfaces[i].BiNormal);
shape.TexGens[i].RenderMaterial = material;
shape.TexGens[i].Scale = MathConstants.oneVector3;
shape.TexGenFlags[i] = CSGSettings.DefaultTexGenFlags;
}
ShapeUtility.EnsureInitialized(shape);
controlMesh.Valid = ControlMeshUtility.Validate(controlMesh, shape);
if (controlMesh.Valid)
{
Debug.Log("The control mesh is valid!");
}
return BrushFactory.CreateBrush(parent, brushName, controlMesh, shape);
}
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Background
In RealtimeCSG, brushes (convex meshes) are represented using the half-edge data structure (see here).
At the moment we convert all of the polygons of a generated convex mesh into planes and then feed those into a RealtimeCSG function that converts a set of planes into a brush. But converting planes (finding the intersection point of 3 planes, where sometimes there are infinite intersections) into a convex mesh is a difficult problem. That's why it often fails and has stability problems.
Your task
Build a function that can take a
PolygonMesh
(see here) and build a brush in the scene, by callingBrushFactory.CreateBrush
(see here). This requires generating the half-edge connectivity data.Files
The C# function has been prepared and only needs contents. Here is a special version of the 2D Shape Editor that you can add as a package:
com.aeternumgames.shapeeditor.zip
Here is the Bounty.cs file, place this file in your RealtimeCSG installation (in your Assets directory):
RealtimeCSGBounty.zip
Try extruding using "RealtimeCSG -> Create Bevel" and you will get a notification in the console window that leads you to the function that needs to be written.
Tips
PolygonMesh
is just aList
ofPolygon
. They are convex n-gons (no triangulation) without duplicate normals.The text was updated successfully, but these errors were encountered: