Merge branch 'main' into dev/1.2

* main:
  Fix gltf accessor's bufferView could be undefined (#2013)
  Fix `IPhysicsScene.removeColliderShape` not cleaned up `eventMap` (#2008)
This commit is contained in:
GuoLei1990
2024-02-29 10:44:35 +08:00
4 changed files with 100 additions and 20 deletions

View File

@@ -134,7 +134,8 @@ export class GLTFUtils {
accessor: IAccessor
): Promise<BufferInfo> {
const componentType = accessor.componentType;
const bufferView = bufferViews[accessor.bufferView];
const bufferViewIndex = accessor.bufferView ?? 0;
const bufferView = bufferViews[bufferViewIndex];
return context.get<Uint8Array>(GLTFParserType.BufferView, accessor.bufferView).then((bufferViewData) => {
const bufferIndex = bufferView.buffer;
@@ -152,7 +153,7 @@ export class GLTFUtils {
// According to the glTF official documentation only byteStride not undefined is allowed
if (bufferStride !== undefined && bufferStride !== elementStride) {
const bufferSlice = Math.floor(byteOffset / bufferStride);
const bufferCacheKey = accessor.bufferView + ":" + componentType + ":" + bufferSlice + ":" + accessorCount;
const bufferCacheKey = bufferViewIndex + ":" + componentType + ":" + bufferSlice + ":" + accessorCount;
const accessorBufferCache = context.accessorBufferCache;
bufferInfo = accessorBufferCache[bufferCacheKey];
if (!bufferInfo) {
@@ -205,7 +206,7 @@ export class GLTFUtils {
*/
static getAccessorData(glTF: IGLTF, accessor: IAccessor, buffers: ArrayBuffer[]): TypedArray {
const bufferViews = glTF.bufferViews;
const bufferView = bufferViews[accessor.bufferView];
const bufferView = bufferViews[accessor.bufferView ?? 0];
const arrayBuffer = buffers[bufferView.buffer];
const accessorByteOffset = accessor.hasOwnProperty("byteOffset") ? accessor.byteOffset : 0;
const bufferViewByteOffset = bufferView.hasOwnProperty("byteOffset") ? bufferView.byteOffset : 0;

View File

@@ -1,5 +1,5 @@
import { ICharacterController, IPhysicsScene } from "@galacean/engine-design";
import { BoundingBox, BoundingSphere, CollisionUtil, Ray, Vector3 } from "@galacean/engine";
import { ICharacterController, IPhysicsScene } from "@galacean/engine-design";
import { DisorderedArray } from "./DisorderedArray";
import { LiteCollider } from "./LiteCollider";
import { LiteHitResult } from "./LiteHitResult";
@@ -65,16 +65,21 @@ export class LitePhysicsScene implements IPhysicsScene {
* {@inheritDoc IPhysicsManager.removeColliderShape }
*/
removeColliderShape(colliderShape: LiteColliderShape): void {
const { _eventPool: eventPool, _currentEvents: currentEvents } = this;
const { _id: shapeID } = colliderShape;
const { _eventPool: eventPool, _currentEvents: currentEvents, _eventMap: eventMap } = this;
const { _id: id } = colliderShape;
for (let i = currentEvents.length - 1; i >= 0; i--) {
const event = currentEvents.get(i);
if (event.index1 == shapeID || event.index2 == shapeID) {
if (event.index1 == id) {
currentEvents.deleteByIndex(i);
eventPool.push(event);
} else if (event.index2 == id) {
currentEvents.deleteByIndex(i);
eventPool.push(event);
// If the shape is big index, should clear from the small index shape subMap
eventMap[event.index1][id] = undefined;
}
}
delete this._eventMap[shapeID];
delete eventMap[id];
}
/**

View File

@@ -116,15 +116,21 @@ export class PhysXPhysicsScene implements IPhysicsScene {
*/
removeColliderShape(colliderShape: PhysXColliderShape) {
const { _eventPool: eventPool, _currentEvents: currentEvents } = this;
const { _id: shapeID } = colliderShape;
const { _id: id } = colliderShape;
const { _eventMap: eventMap } = this._physXManager;
for (let i = currentEvents.length - 1; i >= 0; i--) {
const event = currentEvents.get(i);
if (event.index1 == shapeID || event.index2 == shapeID) {
if (event.index1 == id) {
currentEvents.deleteByIndex(i);
eventPool.push(event);
} else if (event.index2 == id) {
currentEvents.deleteByIndex(i);
eventPool.push(event);
// If the shape is big index, should clear from the small index shape subMap
eventMap[event.index1][id] = undefined;
}
}
delete this._physXManager._eventMap[shapeID];
delete eventMap[id];
}
/**

View File

@@ -1,17 +1,16 @@
import {
Camera,
BoxColliderShape,
Layer,
StaticCollider,
DynamicCollider,
HitResult,
Camera,
CharacterController,
CapsuleColliderShape,
SphereColliderShape,
Script,
Collider,
ColliderShape,
DynamicCollider,
Entity,
Collider
HitResult,
Layer,
Script,
SphereColliderShape,
StaticCollider
} from "@galacean/engine-core";
import { Ray, Vector3 } from "@galacean/engine-math";
import { LitePhysics } from "@galacean/engine-physics-lite";
@@ -136,6 +135,75 @@ describe("Physics Test", () => {
engineLite.run();
});
it("removeShape", () => {
const scene = engineLite.sceneManager.activeScene;
const root = scene.createRootEntity("root");
const removeShapeRoot1 = root.createChild("root");
removeShapeRoot1.transform.position = new Vector3(1000, 1000, 1000);
const enterEvent = [];
const collider1 = removeShapeRoot1.addComponent(StaticCollider);
const box1 = new BoxColliderShape();
enterEvent[box1.id] = [];
collider1.addShape(box1);
removeShapeRoot1.addComponent(
class extends Script {
onTriggerEnter(other: ColliderShape): void {
++enterEvent[box1.id][other.id];
}
}
);
const removeShapeRoot2 = root.createChild("root");
removeShapeRoot2.transform.position = new Vector3(1000, 1000, 1000);
const collider2 = removeShapeRoot2.addComponent(StaticCollider);
const box2 = new BoxColliderShape();
enterEvent[box2.id] = [];
collider2.addShape(box2);
removeShapeRoot2.addComponent(
class extends Script {
onTriggerEnter(other: ColliderShape) {
++enterEvent[box2.id][other.id];
}
}
);
// @ts-ignore
engineLite.physicsManager._update(8);
// Remove collider shape.
removeShapeRoot2.isActive = false;
const removeShapeRoot3 = root.createChild("root");
removeShapeRoot3.transform.position = new Vector3(1000, 1000, 1000);
const collider3 = removeShapeRoot3.addComponent(StaticCollider);
const box3 = new BoxColliderShape();
enterEvent[box3.id] = [];
collider3.addShape(box3);
removeShapeRoot3.addComponent(
class extends Script {
onTriggerEnter(other: ColliderShape) {
++enterEvent[box3.id][other.id];
}
}
);
removeShapeRoot2.isActive = true;
enterEvent[box1.id][box2.id] = 0;
enterEvent[box1.id][box3.id] = 0;
enterEvent[box2.id][box1.id] = 0;
enterEvent[box2.id][box3.id] = 0;
enterEvent[box3.id][box1.id] = 0;
enterEvent[box3.id][box2.id] = 0;
// @ts-ignore
engineLite.physicsManager._update(8);
expect(enterEvent[box1.id][box2.id]).to.eq(1);
expect(enterEvent[box1.id][box3.id]).to.eq(1);
expect(enterEvent[box2.id][box1.id]).to.eq(1);
expect(enterEvent[box2.id][box3.id]).to.eq(1);
expect(enterEvent[box3.id][box1.id]).to.eq(1);
expect(enterEvent[box3.id][box2.id]).to.eq(1);
removeShapeRoot1.destroy();
removeShapeRoot2.destroy();
removeShapeRoot3.destroy();
});
it("constructor", () => {
expect(engineLite.physicsManager.gravity.y).to.eq(-9.81);
expect(engineLite.physicsManager.fixedTimeStep).to.eq(1 / 60);