change wireframe camera geometry
This commit is contained in:
@@ -504,144 +504,189 @@ class GeometryHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Geometry wireframeCamera({
|
static Geometry wireframeCamera({
|
||||||
double sphereRadius = 0.2,
|
double sphereRadius = 0.2,
|
||||||
double frustumDistance = 1.0,
|
double frustumDistance = 1.0,
|
||||||
double frustumNear = 0.5,
|
double frustumNear = 0.5,
|
||||||
double frustumFar = 1.0,
|
double frustumFar = 1.0,
|
||||||
double fov = pi / 3,
|
double fov = pi / 3,
|
||||||
bool normals = true,
|
bool normals = true,
|
||||||
bool uvs = true,
|
bool uvs = true,
|
||||||
}) {
|
double wireThickness = 0.01, // Thickness of the wireframe edges
|
||||||
List<double> verticesList = [];
|
}) {
|
||||||
List<double> normalsList = [];
|
List<double> verticesList = [];
|
||||||
List<double> uvsList = [];
|
List<double> normalsList = [];
|
||||||
List<int> indices = [];
|
List<double> uvsList = [];
|
||||||
|
List<int> indices = [];
|
||||||
|
|
||||||
// Create sphere vertices - keeping bands low for wireframe and to stay within Uint16 limits
|
// Helper function to create a thin triangular tube between two points
|
||||||
int latitudeBands = 6; // Reduced bands for simpler wireframe
|
void addWireSegment(List<double> start, List<double> end) {
|
||||||
int longitudeBands = 6;
|
int baseIndex = verticesList.length ~/ 3;
|
||||||
|
|
||||||
// Generate sphere vertices
|
// Calculate direction vector
|
||||||
for (int latNumber = 0; latNumber <= latitudeBands; latNumber++) {
|
double dx = end[0] - start[0];
|
||||||
double theta = latNumber * pi / latitudeBands;
|
double dy = end[1] - start[1];
|
||||||
double sinTheta = sin(theta);
|
double dz = end[2] - start[2];
|
||||||
double cosTheta = cos(theta);
|
double length = sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
|
||||||
for (int longNumber = 0; longNumber <= longitudeBands; longNumber++) {
|
// Create perpendicular vectors for thickness
|
||||||
double phi = longNumber * 2 * pi / longitudeBands;
|
List<double> perp1, perp2;
|
||||||
double sinPhi = sin(phi);
|
if (dx.abs() < 0.9) {
|
||||||
double cosPhi = cos(phi);
|
perp1 = [0, -dz, dy];
|
||||||
|
} else {
|
||||||
double x = sphereRadius * cosPhi * sinTheta;
|
perp1 = [-dy, dx, 0];
|
||||||
double y = sphereRadius * cosTheta;
|
|
||||||
double z = sphereRadius * sinPhi * sinTheta;
|
|
||||||
|
|
||||||
verticesList.addAll([x, y, z]);
|
|
||||||
normalsList
|
|
||||||
.addAll([x / sphereRadius, y / sphereRadius, z / sphereRadius]);
|
|
||||||
uvsList
|
|
||||||
.addAll([longNumber / longitudeBands, latNumber / latitudeBands]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate sphere line indices
|
// Normalize perpendicular vector
|
||||||
for (int latNumber = 0; latNumber < latitudeBands; latNumber++) {
|
double perpLength = sqrt(perp1[0] * perp1[0] + perp1[1] * perp1[1] + perp1[2] * perp1[2]);
|
||||||
for (int longNumber = 0; longNumber < longitudeBands; longNumber++) {
|
if (perpLength > 0) {
|
||||||
int first = (latNumber * (longitudeBands + 1)) + longNumber;
|
perp1 = [perp1[0] / perpLength * wireThickness,
|
||||||
int second = first + longitudeBands + 1;
|
perp1[1] / perpLength * wireThickness,
|
||||||
int third = first + 1;
|
perp1[2] / perpLength * wireThickness];
|
||||||
|
|
||||||
// Add vertical lines
|
|
||||||
indices.addAll([first, second]);
|
|
||||||
|
|
||||||
// Add horizontal lines
|
|
||||||
if (longNumber < longitudeBands - 1) {
|
|
||||||
indices.addAll([first, third]);
|
|
||||||
} else {
|
|
||||||
// Connect back to first vertex of this latitude
|
|
||||||
indices.addAll([first, latNumber * (longitudeBands + 1)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add center point of sphere for frustum lines
|
// Second perpendicular (cross product)
|
||||||
int sphereCenterIndex = verticesList.length ~/ 3;
|
perp2 = [dy * perp1[2] - dz * perp1[1],
|
||||||
verticesList.addAll([0, 0, 0]); // Sphere center at origin
|
dz * perp1[0] - dx * perp1[2],
|
||||||
normalsList.addAll([0, 0, -1]); // Backward-facing normal
|
dx * perp1[1] - dy * perp1[0]];
|
||||||
uvsList.addAll([0.5, 0.5]); // Center UV coordinate
|
|
||||||
|
// Create 4 vertices around each end point (rectangular cross-section)
|
||||||
// Calculate frustum corners
|
List<List<double>> startVerts = [
|
||||||
double nearHeight = 2.0 * frustumNear * tan(fov / 2);
|
[start[0] + perp1[0], start[1] + perp1[1], start[2] + perp1[2]],
|
||||||
double nearWidth = nearHeight * 1.333; // Assuming 4:3 aspect ratio
|
[start[0] - perp1[0], start[1] - perp1[1], start[2] - perp1[2]],
|
||||||
double farHeight = 2.0 * frustumFar * tan(fov / 2);
|
[start[0] + perp2[0], start[1] + perp2[1], start[2] + perp2[2]],
|
||||||
double farWidth = farHeight * 1.333;
|
[start[0] - perp2[0], start[1] - perp2[1], start[2] - perp2[2]],
|
||||||
|
];
|
||||||
// Store starting index for frustum vertices
|
|
||||||
int nearBaseIndex = verticesList.length ~/ 3;
|
List<List<double>> endVerts = [
|
||||||
|
[end[0] + perp1[0], end[1] + perp1[1], end[2] + perp1[2]],
|
||||||
// Add near rectangle vertices (negative z)
|
[end[0] - perp1[0], end[1] - perp1[1], end[2] - perp1[2]],
|
||||||
verticesList.addAll([
|
[end[0] + perp2[0], end[1] + perp2[1], end[2] + perp2[2]],
|
||||||
-nearWidth / 2, -nearHeight / 2, -frustumNear, // Bottom-left
|
[end[0] - perp2[0], end[1] - perp2[1], end[2] - perp2[2]],
|
||||||
nearWidth / 2, -nearHeight / 2, -frustumNear, // Bottom-right
|
];
|
||||||
nearWidth / 2, nearHeight / 2, -frustumNear, // Top-right
|
|
||||||
-nearWidth / 2, nearHeight / 2, -frustumNear, // Top-left
|
// Add vertices
|
||||||
]);
|
for (var vert in startVerts) {
|
||||||
|
verticesList.addAll(vert);
|
||||||
// Add far rectangle vertices (negative z)
|
normalsList.addAll([vert[0], vert[1], vert[2]]); // Simple normal
|
||||||
int farBaseIndex = verticesList.length ~/ 3;
|
|
||||||
verticesList.addAll([
|
|
||||||
-farWidth / 2, -farHeight / 2, -frustumFar, // Bottom-left
|
|
||||||
farWidth / 2, -farHeight / 2, -frustumFar, // Bottom-right
|
|
||||||
farWidth / 2, farHeight / 2, -frustumFar, // Top-right
|
|
||||||
-farWidth / 2, farHeight / 2, -frustumFar, // Top-left
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Add normals and UVs for frustum vertices
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
normalsList.addAll([0, 0, -1]); // Backward-facing normal
|
|
||||||
uvsList.addAll([0, 0]);
|
uvsList.addAll([0, 0]);
|
||||||
}
|
}
|
||||||
|
for (var vert in endVerts) {
|
||||||
// Add line indices for near rectangle
|
verticesList.addAll(vert);
|
||||||
indices.addAll([
|
normalsList.addAll([vert[0], vert[1], vert[2]]); // Simple normal
|
||||||
nearBaseIndex, nearBaseIndex + 1, // Bottom
|
uvsList.addAll([1, 0]);
|
||||||
nearBaseIndex + 1, nearBaseIndex + 2, // Right
|
}
|
||||||
nearBaseIndex + 2, nearBaseIndex + 3, // Top
|
|
||||||
nearBaseIndex + 3, nearBaseIndex // Left
|
// Create triangular faces for the tube (4 sides, 2 triangles each)
|
||||||
]);
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int next = (i + 1) % 4;
|
||||||
// Add line indices for far rectangle
|
int startCurrent = baseIndex + i;
|
||||||
indices.addAll([
|
int startNext = baseIndex + next;
|
||||||
farBaseIndex, farBaseIndex + 1, // Bottom
|
int endCurrent = baseIndex + 4 + i;
|
||||||
farBaseIndex + 1, farBaseIndex + 2, // Right
|
int endNext = baseIndex + 4 + next;
|
||||||
farBaseIndex + 2, farBaseIndex + 3, // Top
|
|
||||||
farBaseIndex + 3, farBaseIndex // Left
|
// Two triangles per side
|
||||||
]);
|
indices.addAll([startCurrent, endCurrent, startNext]);
|
||||||
|
indices.addAll([startNext, endCurrent, endNext]);
|
||||||
// Add lines connecting near and far rectangles
|
}
|
||||||
indices.addAll([
|
|
||||||
nearBaseIndex, farBaseIndex, // Bottom-left
|
|
||||||
nearBaseIndex + 1, farBaseIndex + 1, // Bottom-right
|
|
||||||
nearBaseIndex + 2, farBaseIndex + 2, // Top-right
|
|
||||||
nearBaseIndex + 3, farBaseIndex + 3 // Top-left
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Add lines from sphere center to near corners
|
|
||||||
indices.addAll([
|
|
||||||
sphereCenterIndex, nearBaseIndex, // To near bottom-left
|
|
||||||
sphereCenterIndex, nearBaseIndex + 1, // To near bottom-right
|
|
||||||
sphereCenterIndex, nearBaseIndex + 2, // To near top-right
|
|
||||||
sphereCenterIndex, nearBaseIndex + 3 // To near top-left
|
|
||||||
]);
|
|
||||||
|
|
||||||
Float32List vertices = Float32List.fromList(verticesList);
|
|
||||||
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
|
||||||
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
|
||||||
|
|
||||||
return Geometry(vertices, Uint16List.fromList(indices),
|
|
||||||
normals: _normals, uvs: _uvs, primitiveType: PrimitiveType.LINES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create sphere wireframe edges
|
||||||
|
int latitudeBands = 6;
|
||||||
|
int longitudeBands = 6;
|
||||||
|
|
||||||
|
// Store sphere points as a flat list for easier access
|
||||||
|
List<List<double>> allSpherePoints = [];
|
||||||
|
|
||||||
|
// Generate sphere vertices and store them
|
||||||
|
for (int latNumber = 0; latNumber <= latitudeBands; latNumber++) {
|
||||||
|
double theta = latNumber * pi / latitudeBands;
|
||||||
|
double sinTheta = sin(theta);
|
||||||
|
double cosTheta = cos(theta);
|
||||||
|
|
||||||
|
for (int longNumber = 0; longNumber <= longitudeBands; longNumber++) {
|
||||||
|
double phi = longNumber * 2 * pi / longitudeBands;
|
||||||
|
double sinPhi = sin(phi);
|
||||||
|
double cosPhi = cos(phi);
|
||||||
|
|
||||||
|
double x = sphereRadius * cosPhi * sinTheta;
|
||||||
|
double y = sphereRadius * cosTheta;
|
||||||
|
double z = sphereRadius * sinPhi * sinTheta;
|
||||||
|
|
||||||
|
allSpherePoints.add([x, y, z]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to get sphere point by lat/long indices
|
||||||
|
List<double> getSpherePoint(int lat, int long) {
|
||||||
|
int index = lat * (longitudeBands + 1) + long;
|
||||||
|
return allSpherePoints[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add sphere wireframe edges
|
||||||
|
for (int latNumber = 0; latNumber < latitudeBands; latNumber++) {
|
||||||
|
for (int longNumber = 0; longNumber < longitudeBands; longNumber++) {
|
||||||
|
// Vertical lines
|
||||||
|
addWireSegment(getSpherePoint(latNumber, longNumber),
|
||||||
|
getSpherePoint(latNumber + 1, longNumber));
|
||||||
|
|
||||||
|
// Horizontal lines
|
||||||
|
addWireSegment(getSpherePoint(latNumber, longNumber),
|
||||||
|
getSpherePoint(latNumber, (longNumber + 1) % longitudeBands));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate frustum corners
|
||||||
|
double nearHeight = 2.0 * frustumNear * tan(fov / 2);
|
||||||
|
double nearWidth = nearHeight * 1.333;
|
||||||
|
double farHeight = 2.0 * frustumFar * tan(fov / 2);
|
||||||
|
double farWidth = farHeight * 1.333;
|
||||||
|
|
||||||
|
// Frustum corner points
|
||||||
|
List<double> sphereCenter = [0, 0, 0];
|
||||||
|
List<List<double>> nearCorners = [
|
||||||
|
[-nearWidth / 2, -nearHeight / 2, -frustumNear], // Bottom-left
|
||||||
|
[nearWidth / 2, -nearHeight / 2, -frustumNear], // Bottom-right
|
||||||
|
[nearWidth / 2, nearHeight / 2, -frustumNear], // Top-right
|
||||||
|
[-nearWidth / 2, nearHeight / 2, -frustumNear], // Top-left
|
||||||
|
];
|
||||||
|
|
||||||
|
List<List<double>> farCorners = [
|
||||||
|
[-farWidth / 2, -farHeight / 2, -frustumFar], // Bottom-left
|
||||||
|
[farWidth / 2, -farHeight / 2, -frustumFar], // Bottom-right
|
||||||
|
[farWidth / 2, farHeight / 2, -frustumFar], // Top-right
|
||||||
|
[-farWidth / 2, farHeight / 2, -frustumFar], // Top-left
|
||||||
|
];
|
||||||
|
|
||||||
|
// Add frustum wireframe edges
|
||||||
|
|
||||||
|
// Near rectangle edges
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
addWireSegment(nearCorners[i], nearCorners[(i + 1) % 4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Far rectangle edges
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
addWireSegment(farCorners[i], farCorners[(i + 1) % 4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connecting edges between near and far
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
addWireSegment(nearCorners[i], farCorners[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lines from sphere center to near corners
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
addWireSegment(sphereCenter, nearCorners[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Float32List vertices = Float32List.fromList(verticesList);
|
||||||
|
Float32List? _normals = normals ? Float32List.fromList(normalsList) : null;
|
||||||
|
Float32List? _uvs = uvs ? Float32List.fromList(uvsList) : null;
|
||||||
|
|
||||||
|
return Geometry(vertices, Uint16List.fromList(indices),
|
||||||
|
normals: _normals, uvs: _uvs, primitiveType: PrimitiveType.TRIANGLES);
|
||||||
|
}
|
||||||
|
|
||||||
static Geometry fromAabb3(Aabb3 aabb,
|
static Geometry fromAabb3(Aabb3 aabb,
|
||||||
{bool normals = true, bool uvs = true}) {
|
{bool normals = true, bool uvs = true}) {
|
||||||
// Get the center and half extents from the AABB
|
// Get the center and half extents from the AABB
|
||||||
|
|||||||
Reference in New Issue
Block a user