Skip to content

Commit

Permalink
fix: 3d scene error (#6519)
Browse files Browse the repository at this point in the history
* fix: fix 3d element rendering exceptions

* refactor: 3d plugin uses an independent cache

---------

Co-authored-by: antv <[email protected]>
  • Loading branch information
Aarebecca and antv authored Nov 15, 2024
1 parent 6a0482a commit a24fa6e
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 23 deletions.
10 changes: 9 additions & 1 deletion packages/g6-extension-3d/src/elements/capsule.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DisplayObjectConfig } from '@antv/g';
import type { CapsuleGeometryProps, ProceduralGeometry as GGeometry } from '@antv/g-plugin-3d';
import { CapsuleGeometry } from '@antv/g-plugin-3d';
import type { Vector3 } from '@antv/g6';
import { deepMix } from '@antv/util';
import { createGeometry } from '../utils/geometry';
import type { BaseNode3DStyleProps } from './base-node-3d';
Expand Down Expand Up @@ -30,9 +31,16 @@ export class Capsule extends BaseNode3D<CapsuleStyleProps> {
super(deepMix({}, { style: Capsule.defaultStyleProps }, options));
}

protected getSize(attributes: CapsuleStyleProps = this.attributes): Vector3 {
const { size } = attributes;
if (typeof size === 'number') return [size / 4, size, size];
return super.getSize();
}

protected getGeometry(attributes: Required<CapsuleStyleProps>): GGeometry<any> {
const size = this.getSize();
const { radius = size[0] / 2, height = size[1], heightSegments, sides } = attributes;
const { radius = size[0], height = size[1], heightSegments, sides } = attributes;

return createGeometry('capsule', this.device, CapsuleGeometry, { radius, height, heightSegments, sides });
}
}
15 changes: 8 additions & 7 deletions packages/g6-extension-3d/src/elements/cone.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DisplayObjectConfig } from '@antv/g';
import type { ConeGeometryProps, ProceduralGeometry as GGeometry } from '@antv/g-plugin-3d';
import { ConeGeometry } from '@antv/g-plugin-3d';
import type { Vector3 } from '@antv/g6';
import { deepMix } from '@antv/util';
import { createGeometry } from '../utils/geometry';
import type { BaseNode3DStyleProps } from './base-node-3d';
Expand Down Expand Up @@ -30,15 +31,15 @@ export class Cone extends BaseNode3D<ConeStyleProps> {
super(deepMix({}, { style: Cone.defaultStyleProps }, options));
}

protected getSize(attributes: ConeStyleProps = this.attributes): Vector3 {
const { size } = attributes;
if (typeof size === 'number') return [size / 2, 0, size];
return super.getSize();
}

protected getGeometry(attributes: Required<ConeStyleProps>): GGeometry<any> {
const size = this.getSize();
const {
baseRadius = size[0] / 2,
peakRadius = size[1] / 2,
height = size[2],
heightSegments,
capSegments,
} = attributes;
const { baseRadius = size[0], peakRadius = size[1], height = size[2], heightSegments, capSegments } = attributes;
return createGeometry('cone', this.device, ConeGeometry, {
baseRadius,
peakRadius,
Expand Down
9 changes: 8 additions & 1 deletion packages/g6-extension-3d/src/elements/cylinder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DisplayObjectConfig } from '@antv/g';
import type { CylinderGeometryProps, ProceduralGeometry as GGeometry } from '@antv/g-plugin-3d';
import { CylinderGeometry } from '@antv/g-plugin-3d';
import type { Vector3 } from '@antv/g6';
import { deepMix } from '@antv/util';
import { createGeometry } from '../utils/geometry';
import type { BaseNode3DStyleProps } from './base-node-3d';
Expand Down Expand Up @@ -30,9 +31,15 @@ export class Cylinder extends BaseNode3D<CylinderStyleProps> {
super(deepMix({}, { style: Cylinder.defaultStyleProps }, options));
}

protected getSize(attributes: CylinderStyleProps = this.attributes): Vector3 {
const { size } = attributes;
if (typeof size === 'number') return [size / 2, size, 0];
return super.getSize();
}

protected getGeometry(attributes: Required<CylinderStyleProps>): GGeometry<any> {
const size = this.getSize();
const { radius = size[0] / 2, height = size[1], heightSegments, capSegments } = attributes;
const { radius = size[0], height = size[1], heightSegments, capSegments } = attributes;
return createGeometry('cylinder', this.device, CylinderGeometry, { radius, height, heightSegments, capSegments });
}
}
9 changes: 8 additions & 1 deletion packages/g6-extension-3d/src/elements/torus.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DisplayObjectConfig } from '@antv/g';
import type { ProceduralGeometry as GGeometry, TorusGeometryProps } from '@antv/g-plugin-3d';
import { TorusGeometry } from '@antv/g-plugin-3d';
import type { Vector3 } from '@antv/g6';
import { deepMix } from '@antv/util';
import { createGeometry } from '../utils/geometry';
import type { BaseNode3DStyleProps } from './base-node-3d';
Expand Down Expand Up @@ -30,9 +31,15 @@ export class Torus extends BaseNode3D<TorusStyleProps> {
super(deepMix({}, { style: Torus.defaultStyleProps }, options));
}

protected getSize(attributes: TorusStyleProps = this.attributes): Vector3 {
const { size } = attributes;
if (typeof size === 'number') return [size / 8, size / 2, 0];
return super.getSize();
}

protected getGeometry(attributes: Required<TorusStyleProps>): GGeometry<any> {
const size = this.getSize();
const { tubeRadius = size[0] / 2, ringRadius = size[1] / 2, segments, sides } = attributes;
const { tubeRadius = size[0], ringRadius = size[1], segments, sides } = attributes;
return createGeometry('torus', this.device, TorusGeometry, { tubeRadius, ringRadius, segments, sides });
}
}
19 changes: 10 additions & 9 deletions packages/g6-extension-3d/src/utils/material.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import type { Material as GMaterial } from '@antv/g-plugin-3d';
import { MeshBasicMaterial, MeshLambertMaterial, MeshPhongMaterial, PointMaterial } from '@antv/g-plugin-3d';
import type { Plugin } from '@antv/g-plugin-device-renderer';
import { get, set } from '@antv/util';
import type { Material } from '../types';
import { getCacheKey } from './cache';
import { TupleMap } from './map';
import { createTexture } from './texture';

let PLUGIN: Plugin;
type MaterialCache = TupleMap<symbol, string | TexImageSource | undefined, GMaterial>;

const MATERIAL_CACHE = new TupleMap<symbol, string | TexImageSource | undefined, GMaterial>();
const MATERIAL_CACHE_KEY = '__MATERIAL_CACHE__';

const MATERIAL_MAP = {
basic: MeshBasicMaterial,
Expand All @@ -27,16 +28,16 @@ const MATERIAL_MAP = {
* @returns <zh/> 材质对象 <en/> material object
*/
export function createMaterial(plugin: Plugin, options: Material, texture?: string | TexImageSource): GMaterial {
if (!PLUGIN) PLUGIN = plugin;
else if (PLUGIN !== plugin) {
PLUGIN = plugin;
MATERIAL_CACHE.clear();
let cache: MaterialCache = get(plugin, MATERIAL_CACHE_KEY);
if (!cache) {
cache = new TupleMap();
set(plugin, MATERIAL_CACHE_KEY, cache);
}

const key = getCacheKey(options);

if (MATERIAL_CACHE.has(key, texture)) {
return MATERIAL_CACHE.get(key, texture)!;
if (cache.has(key, texture)) {
return cache.get(key, texture)!;
}

const device = plugin.getDevice();
Expand All @@ -45,6 +46,6 @@ export function createMaterial(plugin: Plugin, options: Material, texture?: stri

// @ts-expect-error ignore
const material = new Ctor(device, { map: createTexture(plugin, map), ...opts });
MATERIAL_CACHE.set(key, texture, material);
cache.set(key, texture, material);
return material;
}
19 changes: 15 additions & 4 deletions packages/g6-extension-3d/src/utils/texture.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { Texture } from '@antv/g-device-api';
import type { Plugin } from '@antv/g-plugin-device-renderer';
import { get, set } from '@antv/util';

const TEXTURE_CACHE = new Map<string | TexImageSource, Texture>();
type TextureCache = Map<string | TexImageSource, Texture>;

const TEXTURE_CACHE_KEY = '__TEXTURE_CACHE__';

// const TEXTURE_CACHE = new Map<string | TexImageSource, Texture>();

/**
* <zh/> 创建纹理,支持缓存
Expand All @@ -14,10 +19,16 @@ const TEXTURE_CACHE = new Map<string | TexImageSource, Texture>();
export function createTexture(plugin: Plugin, src?: string | TexImageSource): Texture | undefined {
if (!src) return;

if (TEXTURE_CACHE.has(src)) {
return TEXTURE_CACHE.get(src);
let cache: TextureCache = get(plugin, TEXTURE_CACHE_KEY);
if (!cache) {
cache = new Map();
set(plugin, TEXTURE_CACHE_KEY, cache);
}

if (cache.has(src)) {
return cache.get(src);
}
const texture = plugin.loadTexture(src);
TEXTURE_CACHE.set(src, texture);
cache.set(src, texture);
return texture;
}

0 comments on commit a24fa6e

Please sign in to comment.