fix winding order in GeometryHelper

This commit is contained in:
Nick Fisher
2024-09-13 10:35:33 +08:00
parent d476d78e2b
commit 98fefd0e52

View File

@@ -3,7 +3,7 @@ import 'dart:math';
class Geometry { class Geometry {
final List<double> vertices; final List<double> vertices;
final List<int> indices; final List<int> indices;
final List<double> normals; final List<double>? normals;
Geometry(this.vertices, this.indices, this.normals); Geometry(this.vertices, this.indices, this.normals);
@@ -15,7 +15,7 @@ class Geometry {
} }
class GeometryHelper { class GeometryHelper {
static Geometry sphere() { static Geometry sphere() {
int latitudeBands = 20; int latitudeBands = 20;
int longitudeBands = 20; int longitudeBands = 20;
@@ -138,28 +138,28 @@ class GeometryHelper {
final indices = [ final indices = [
// Front face // Front face
0, 3, 2, 0, 2, 1, 0, 1, 2, 0, 2, 3,
// Back face // Back face
4, 7, 6, 4, 6, 5, 4, 5, 6, 4, 6, 7,
// Top face // Top face
8, 11, 10, 8, 10, 9, 8, 9, 10, 8, 10, 11,
// Bottom face // Bottom face
12, 15, 14, 12, 14, 13, 12, 13, 14, 12, 14, 15,
// Right face // Right face
16, 19, 18, 16, 18, 17, 16, 17, 18, 16, 18, 19,
// Left face // Left face
20, 23, 22, 20, 22, 21 20, 21, 22, 20, 22, 23
]; ];
return Geometry(vertices, indices, normals); return Geometry(vertices, indices, normals);
} }
static Geometry cylinder({double radius = 1.0, double length = 1.0}) { static Geometry cylinder({double radius = 1.0, double length = 1.0}) {
int segments = 32; int segments = 32;
List<double> vertices = []; List<double> vertices = [];
List<double> normals = [];
List<int> indices = []; List<int> indices = [];
// Create vertices // Create vertices and normals
for (int i = 0; i <= segments; i++) { for (int i = 0; i <= segments; i++) {
double theta = i * 2 * pi / segments; double theta = i * 2 * pi / segments;
double x = radius * cos(theta); double x = radius * cos(theta);
@@ -167,8 +167,11 @@ class GeometryHelper {
// Top circle // Top circle
vertices.addAll([x, length / 2, z]); vertices.addAll([x, length / 2, z]);
normals.addAll([x / radius, 0, z / radius]);
// Bottom circle // Bottom circle
vertices.addAll([x, -length / 2, z]); vertices.addAll([x, -length / 2, z]);
normals.addAll([x / radius, 0, z / radius]);
} }
// Create indices // Create indices
@@ -187,19 +190,28 @@ class GeometryHelper {
indices.addAll([bottomFirst, bottomSecond, topSecond]); indices.addAll([bottomFirst, bottomSecond, topSecond]);
} }
// Add center vertices for top and bottom faces // Add center vertices and normals for top and bottom faces
vertices.addAll([0, length / 2, 0]); // Top center vertices.addAll([0, length / 2, 0]); // Top center
normals.addAll([0, 1, 0]);
vertices.addAll([0, -length / 2, 0]); // Bottom center vertices.addAll([0, -length / 2, 0]); // Bottom center
normals.addAll([0, -1, 0]);
return Geometry(vertices:vertices, indices:indices, normals:normals); // Add top and bottom face normals
for (int i = 0; i <= segments; i++) {
normals.addAll([0, 1, 0]); // Top face normal
normals.addAll([0, -1, 0]); // Bottom face normal
}
return Geometry(vertices, indices, normals);
} }
static Geometry conic({double radius = 1.0, double length = 1.0}) { static Geometry conic({double radius = 1.0, double length = 1.0}) {
int segments = 32; int segments = 32;
List<double> vertices = []; List<double> vertices = [];
List<double> normals = [];
List<int> indices = []; List<int> indices = [];
// Create vertices // Create vertices and normals
for (int i = 0; i <= segments; i++) { for (int i = 0; i <= segments; i++) {
double theta = i * 2 * pi / segments; double theta = i * 2 * pi / segments;
double x = radius * cos(theta); double x = radius * cos(theta);
@@ -207,9 +219,16 @@ class GeometryHelper {
// Base circle // Base circle
vertices.addAll([x, 0, z]); vertices.addAll([x, 0, z]);
// Calculate normal for the side
double nx = x / sqrt(x * x + length * length);
double nz = z / sqrt(z * z + length * length);
double ny = radius / sqrt(radius * radius + length * length);
normals.addAll([nx, ny, nz]);
} }
// Apex // Apex
vertices.addAll([0, length, 0]); vertices.addAll([0, length, 0]);
normals.addAll([0, 1, 0]); // Normal at apex points straight up
// Create indices // Create indices
for (int i = 0; i < segments; i++) { for (int i = 0; i < segments; i++) {
@@ -219,7 +238,34 @@ class GeometryHelper {
indices.addAll([i, segments, i + 1]); indices.addAll([i, segments, i + 1]);
} }
return Geometry(vertices:vertices, indices:indices, normals:normals); // Add base face normals
for (int i = 0; i <= segments; i++) {
normals.addAll([0, -1, 0]); // Base face normal
} }
return Geometry(vertices, indices, normals);
}
static Geometry plane({double width = 1.0, double height = 1.0}) {
List<double> vertices = [
-width / 2, 0, -height / 2,
width / 2, 0, -height / 2,
width / 2, 0, height / 2,
-width / 2, 0, height / 2,
];
List<double> normals = [
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
];
List<int> indices = [
0, 1, 2,
0, 2, 3,
];
return Geometry(vertices, indices, normals);
} }
} }