Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions doc/HomagGroup.Blazor3D.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions src/dotnet/Blazor3D/Blazor3D/Geometires/TrianglesGeometry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using HomagGroup.Blazor3D.Core;
using HomagGroup.Blazor3D.Maths;

namespace HomagGroup.Blazor3D.Geometires
{
/// <summary>
/// <para>Geometry for a mesh from multiple triangles.</para>
/// <para>This class inherits from <see cref="BufferGeometry"/></para>
/// </summary>
/// <inheritdoc><see cref="BufferGeometry"/></inheritdoc>
public sealed class TrianglesGeometry : BufferGeometry
{
public TrianglesGeometry() : base("TrianglesGeometry")
{ }

/// <summary>
/// Lists of vertices for each polygon. Each vertex has a position and a normal vector.
/// </summary>
public List<Triangle3> Triangles { get; set; } = new List<Triangle3>();
}
}
68 changes: 68 additions & 0 deletions src/dotnet/Blazor3D/Blazor3D/Maths/Triangle3.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
namespace HomagGroup.Blazor3D.Maths
{
/// <summary>
/// A triangle in 3D space with normal vectors for each vertex.
/// </summary>
public sealed class Triangle3
{
/// <summary>
/// Position of the first vertex.
/// </summary>
public Vector3 PositionA { get; set; } = new Vector3();

/// <summary>
/// Position of the second vertex.
/// </summary>
public Vector3 PositionB { get; set; } = new Vector3();

/// <summary>
/// Position of the third vertex.
/// </summary>
public Vector3 PositionC { get; set; } = new Vector3();

/// <summary>
/// Normal vector of the first vertex.
/// </summary>
public Vector3 NormalA { get; set; } = new Vector3();

/// <summary>
/// Normal vector of the second vertex.
/// </summary>
public Vector3 NormalB { get; set; } = new Vector3();

/// <summary>
/// Normal vector of the third vertex.
/// </summary>
public Vector3 NormalC { get; set; } = new Vector3();

/// <summary>
/// Uses the positions of the vertices to calculate normal vectors perpendicular to the face, assuming the vertices are ordered counterclockwise when seen from the outside.
/// </summary>
public Triangle3 WithNormalsFromPositions()
{
var aToB = new System.Numerics.Vector3(
(float)(this.PositionB.X - this.PositionA.X),
(float)(this.PositionB.Y - this.PositionA.Y),
(float)(this.PositionB.Z - this.PositionA.Z)
);
var aToC = new System.Numerics.Vector3(
(float)(this.PositionC.X - this.PositionA.X),
(float)(this.PositionC.Y - this.PositionA.Y),
(float)(this.PositionC.Z - this.PositionA.Z)
);
var normal = System.Numerics.Vector3.Normalize(
System.Numerics.Vector3.Cross(aToB, aToC)
);
var resultNormal = new Vector3(normal.X, normal.Y, normal.Z);
return new Triangle3
{
PositionA = this.PositionA,
PositionB = this.PositionB,
PositionC = this.PositionC,
NormalA = resultNormal,
NormalB = resultNormal,
NormalC = resultNormal
};
}
}
}
2 changes: 1 addition & 1 deletion src/dotnet/Blazor3D/Blazor3D/wwwroot/js/bundle.js

Large diffs are not rendered by default.

48 changes: 47 additions & 1 deletion src/dotnet/Blazor3D/TestServer/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,15 @@
var plane = new Plane(new Vector3(-1, 1, 1), 1);
scene.Add(new PlaneHelper(plane, 1, "green"));

scene.Add(
new Mesh()
{
Geometry = CubeFromTriangles(),
Position = new Vector3(10, 0, 0),
EdgesMaterial = new LineBasicMaterial{ Color="black" }
}
);


}

Expand Down Expand Up @@ -379,7 +388,44 @@
{
await View3D1.SelectByUuidAsync(selectObjectGuid.Value);
}


}

private TrianglesGeometry CubeFromTriangles()
{
var left = -1;
var right = 1;
var top = 1;
var bottom = -1;
var front = 1;
var back = -1;
var ltf = new Vector3(left, top, front);
var rtf = new Vector3(right, top, front);
var lbf = new Vector3(left, bottom, front);
var rbf = new Vector3(right, bottom, front);
var ltb = new Vector3(left, top, back);
var rtb = new Vector3(right, top, back);
var lbb = new Vector3(left, bottom, back);
var rbb = new Vector3(right, bottom, back);
return
new TrianglesGeometry()
{
Triangles = new List<Triangle3>
{
new Triangle3{PositionA=ltf, PositionB=lbf, PositionC=rbf}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltf, PositionB=rbf, PositionC=rtf}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltb, PositionB=rtb, PositionC=rbb}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltb, PositionB=rbb, PositionC=lbb}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltb, PositionB=lbb, PositionC=lbf}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltb, PositionB=lbf, PositionC=ltf}.WithNormalsFromPositions(),
new Triangle3{PositionA=rtf, PositionB=rbf, PositionC=rbb}.WithNormalsFromPositions(),
new Triangle3{PositionA=rtf, PositionB=rbb, PositionC=rtb}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltf, PositionB=rtf, PositionC=rtb}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltf, PositionB=rtb, PositionC=ltb}.WithNormalsFromPositions(),
new Triangle3{PositionA=lbf, PositionB=lbb, PositionC=rbb}.WithNormalsFromPositions(),
new Triangle3{PositionA=lbf, PositionB=rbb, PositionC=rbf}.WithNormalsFromPositions(),
}
};
}
}

47 changes: 47 additions & 0 deletions src/dotnet/Blazor3D/TestWebAsm/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@using HomagGroup.Blazor3D.Enums
@using HomagGroup.Blazor3D.Geometires
@using HomagGroup.Blazor3D.Lights
@using HomagGroup.Blazor3D.Materials
@using HomagGroup.Blazor3D.Maths
@using HomagGroup.Blazor3D.Objects
@using HomagGroup.Blazor3D.Scenes
Expand Down Expand Up @@ -73,6 +74,15 @@
Scale = new Vector3(0.5f, 1f, 1f)
});

scene.Add(
new Mesh()
{
Geometry = CubeFromTriangles(),
Position = new Vector3(5, 0, 0),
EdgesMaterial = new LineBasicMaterial { Color = "black" }
}
);

return base.OnInitializedAsync();
}

Expand All @@ -93,5 +103,42 @@
// await View3D1.SetCameraPositionAsync(new Vector3(0, 1, 5));
}

private TrianglesGeometry CubeFromTriangles()
{
var left = -1;
var right = 1;
var top = 1;
var bottom = -1;
var front = 1;
var back = -1;
var ltf = new Vector3(left, top, front);
var rtf = new Vector3(right, top, front);
var lbf = new Vector3(left, bottom, front);
var rbf = new Vector3(right, bottom, front);
var ltb = new Vector3(left, top, back);
var rtb = new Vector3(right, top, back);
var lbb = new Vector3(left, bottom, back);
var rbb = new Vector3(right, bottom, back);
return
new TrianglesGeometry()
{
Triangles = new List<Triangle3>
{
new Triangle3{PositionA=ltf, PositionB=lbf, PositionC=rbf}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltf, PositionB=rbf, PositionC=rtf}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltb, PositionB=rtb, PositionC=rbb}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltb, PositionB=rbb, PositionC=lbb}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltb, PositionB=lbb, PositionC=lbf}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltb, PositionB=lbf, PositionC=ltf}.WithNormalsFromPositions(),
new Triangle3{PositionA=rtf, PositionB=rbf, PositionC=rbb}.WithNormalsFromPositions(),
new Triangle3{PositionA=rtf, PositionB=rbb, PositionC=rtb}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltf, PositionB=rtf, PositionC=rtb}.WithNormalsFromPositions(),
new Triangle3{PositionA=ltf, PositionB=rtb, PositionC=ltb}.WithNormalsFromPositions(),
new Triangle3{PositionA=lbf, PositionB=lbb, PositionC=rbb}.WithNormalsFromPositions(),
new Triangle3{PositionA=lbf, PositionB=rbb, PositionC=rbf}.WithNormalsFromPositions(),
}
};
}

}

32 changes: 32 additions & 0 deletions src/javascript/Builders/GeometryBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,38 @@ class GeometryBuilder {
return geometry;
}

if (options.type == "TrianglesGeometry") {
const geometry = new THREE.BufferGeometry();
const vertices = [];
const normals = [];
let groupIndex = 0;
let groupStartVertexIndex = 0;

for (let i = 0, l = options.triangles.length; i < l; i ++) {
const triangle = options.triangles[i];

vertices.push(
triangle.positionA.x, triangle.positionA.y, triangle.positionA.z,
triangle.positionB.x, triangle.positionB.y, triangle.positionB.z,
triangle.positionC.x, triangle.positionC.y, triangle.positionC.z
);
normals.push(
triangle.normalA.x, triangle.normalA.y, triangle.normalA.z,
triangle.normalB.x, triangle.normalB.y, triangle.normalB.z,
triangle.normalC.x, triangle.normalC.y, triangle.normalC.z
);

geometry.addGroup(groupStartVertexIndex, 3, groupIndex);
groupIndex++;
groupStartVertexIndex += 3;
}

geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));
geometry.uuid = options.uuid;
return geometry;
}

console.log("geometry type not found", options);
}
}
Expand Down