Skip to content

Commit

Permalink
feat: calculate bbox of Mesh correctly #925
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoiver committed May 22, 2023
1 parent b9efa0d commit c5d0c89
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 31 deletions.
2 changes: 2 additions & 0 deletions packages/g-lite/src/css/StyleValueRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,8 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry {
// <Text> use textAlign & textBaseline instead of anchor
if (nodeName === Shape.TEXT) {
delete parsedStyle.anchor;
} else if (nodeName === Shape.MESH) {
parsedStyle.anchor[2] = 0.5;
}

const center: Tuple3Number = [
Expand Down
32 changes: 27 additions & 5 deletions packages/g-plugin-3d/src/geometries/CubeGeometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,11 @@ export class CubeGeometry extends ProceduralGeometry<CubeGeometryProps> {
const indices: number[] = [];
let vcounter = 0;

const generateFace = (side: number, uSegments: number, vSegments: number) => {
const generateFace = (
side: number,
uSegments: number,
vSegments: number,
) => {
let u: number;
let v: number;
let i: number;
Expand All @@ -160,15 +164,29 @@ export class CubeGeometry extends ProceduralGeometry<CubeGeometryProps> {
const temp2 = vec3.create();
const temp3 = vec3.create();
const r = vec3.create();
vec3.lerp(temp1, corners[faceAxes[side][0]], corners[faceAxes[side][1]], i / uSegments);
vec3.lerp(temp2, corners[faceAxes[side][0]], corners[faceAxes[side][2]], j / vSegments);
vec3.lerp(
temp1,
corners[faceAxes[side][0]],
corners[faceAxes[side][1]],
i / uSegments,
);
vec3.lerp(
temp2,
corners[faceAxes[side][0]],
corners[faceAxes[side][2]],
j / vSegments,
);
vec3.sub(temp3, temp2, corners[faceAxes[side][0]]);
vec3.add(r, temp1, temp3);
u = i / uSegments;
v = j / vSegments;

positions.push(r[0], r[1], r[2]);
normals.push(faceNormals[side][0], faceNormals[side][1], faceNormals[side][2]);
normals.push(
faceNormals[side][0],
faceNormals[side][1],
faceNormals[side][2],
);
uvs.push(u, 1.0 - v);
// pack as 3x2
// 1/3 will be empty, but it's either that or stretched pixels
Expand All @@ -183,7 +201,11 @@ export class CubeGeometry extends ProceduralGeometry<CubeGeometryProps> {

if (i < uSegments && j < vSegments) {
indices.push(vcounter + vSegments + 1, vcounter + 1, vcounter);
indices.push(vcounter + vSegments + 1, vcounter + vSegments + 2, vcounter + 1);
indices.push(
vcounter + vSegments + 1,
vcounter + vSegments + 2,
vcounter + 1,
);
}

vcounter++;
Expand Down
71 changes: 55 additions & 16 deletions packages/g-plugin-3d/src/geometries/ProceduralGeometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,39 @@ import {
VertexAttributeLocation,
VertexBufferFrequency,
} from '@antv/g-plugin-device-renderer';
import type { Device } from '@antv/g-plugin-device-renderer';
import { mat4, vec3, vec4 } from 'gl-matrix';

export abstract class ProceduralGeometry<GeometryProps> extends BufferGeometry<GeometryProps> {
export interface Topology {
indices: number[];
positions: number[];
normals: number[];
uvs: number[];
uv1s: number[];
}

export abstract class ProceduralGeometry<
GeometryProps,
> extends BufferGeometry<GeometryProps> {
constructor(device: Device, props: Partial<GeometryProps> = {}) {
super(device, props);
this.topology = this.createTopology();
}

protected topology: Topology;

/**
* flip Y, since +Y is down in G's world coords
*/
protected flipYMatrix = mat4.fromScaling(mat4.create(), vec3.fromValues(1, -1, 1));
protected flipYMatrix = mat4.fromScaling(
mat4.create(),
vec3.fromValues(1, -1, 1),
);

/**
* create geometry attributes
*/
protected abstract createTopology(): {
indices: number[];
positions: number[];
normals: number[];
uvs: number[];
uv1s: number[];
};
protected abstract createTopology(): Topology;

protected applyMa4Position(mat: mat4, positions: ArrayBufferView) {
const v = vec4.create();
Expand Down Expand Up @@ -71,29 +86,53 @@ export abstract class ProceduralGeometry<GeometryProps> extends BufferGeometry<G
}

protected rebuildPosition() {
const { positions } = this.createTopology();
this.topology = this.createTopology();

const p = Float32Array.from(positions);
const p = Float32Array.from(this.topology.positions);
this.applyMa4Position(this.flipYMatrix, p);

this.dirty = true;
}

applyMat4(mat: mat4) {
this.applyMa4Position(mat, this.vertices[VertexAttributeBufferIndex.POSITION]);
this.applyMa4Position(
mat,
this.vertices[VertexAttributeBufferIndex.POSITION],
);
this.applyMa4Normal(mat, this.vertices[VertexAttributeBufferIndex.NORMAL]);
// transform tangent
}

computeBoundingBox(): AABB {
// 根据 ProceduralGeometryAttributeLocation.POSITION 计算
// const buffer = this.getVertexBuffer(VertexAttributeBufferIndex.POSITION);
const { positions } = this.topology;

let maxX = -Infinity;
let maxY = -Infinity;
let maxZ = -Infinity;
let minX = Infinity;
let minY = Infinity;
let minZ = Infinity;
for (let i = 0; i < positions.length; i += 3) {
const x = positions[i];
const y = positions[i + 1];
const z = positions[i + 2];

maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
maxZ = Math.max(maxZ, z);
minX = Math.min(minX, x);
minY = Math.min(minY, y);
minZ = Math.min(minZ, z);
}

const aabb = new AABB();
aabb.setMinMax([minX, minY, minZ], [maxX, maxY, maxZ]);

return new AABB();
return aabb;
}

build() {
const { indices, positions, normals, uvs } = this.createTopology();
const { indices, positions, normals, uvs } = this.topology;

this.setIndexBuffer(new Uint32Array(indices));
this.vertexCount = indices.length;
Expand Down
1 change: 1 addition & 0 deletions packages/g-plugin-device-renderer/src/Mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export class Mesh<GeometryProps = any> extends DisplayObject<
y: '',
z: '',
lineWidth: 0,
anchor: [0.5, 0.5, 0.5],
...style,
},
...rest,
Expand Down
19 changes: 9 additions & 10 deletions packages/g-plugin-device-renderer/src/MeshUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@ export class MeshUpdater implements GeometryAABBUpdater<ParsedMeshStyleProps> {
update(parsedStyle: ParsedMeshStyleProps) {
const { geometry } = parsedStyle;

geometry.computeBoundingBox();
// const minX = Math.min(x1, x2);
// const maxX = Math.max(x1, x2);
// const minY = Math.min(y1, y2);
// const maxY = Math.max(y1, y2);
const aabb = geometry.computeBoundingBox();
const max = aabb.getMax();
const min = aabb.getMin();

// const width = maxX - minX;
// const height = maxY - minY;
const width = max[0] - min[0];
const height = max[1] - min[1];
const depth = max[2] - min[2];

return {
width: 0,
height: 0,
depth: 0,
width,
height,
depth,
};
}
}

0 comments on commit c5d0c89

Please sign in to comment.