Skip to content

Commit b7ba9f7

Browse files
authored
1.适配DirectorEvent.RESET后调用physicscontactmanager.clear. (#99)
* 1.适配DirectorEvent.RESET后调用physicscontactmanager.clear. 2.根据1来调整,box2d, box2d-jsb, box2d-wam * add empty clearContacts * add clearContacts interface
1 parent ab670c4 commit b7ba9f7

11 files changed

Lines changed: 122 additions & 53 deletions

File tree

cocos/physics-2d/box2d-jsb/physics-world.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,4 +479,7 @@ export class b2PhysicsWorld implements IPhysicsWorld {
479479
c.emit(Contact2DType.POST_SOLVE);
480480
c._setImpulse(null);
481481
}
482+
clearContacts (): void {
483+
PhysicsContactManager.clear();
484+
}
482485
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
Copyright (c) 2024 Xiamen Yaji Software Co., Ltd.
3+
https://www.cocos.com/
4+
*/
5+
import { B2ObjectType, getTSObjectFromWASMObjectPtr } from './instantiated';
6+
import { PhysicsContact } from './physics-contact';
7+
8+
const pools: PhysicsContact[] = [];
9+
10+
export class PhysicsContactManager {
11+
static get (b2contact: number): PhysicsContact {
12+
let c = pools.pop();
13+
if (!c) {
14+
c = new PhysicsContact();
15+
}
16+
c.init(b2contact);
17+
return c;
18+
}
19+
static find (b2contact: number): PhysicsContact | null {
20+
return getTSObjectFromWASMObjectPtr<PhysicsContact>(B2ObjectType.Contact, b2contact);
21+
}
22+
23+
static put (b2contact: number): void {
24+
const c = getTSObjectFromWASMObjectPtr<PhysicsContact>(B2ObjectType.Contact, b2contact);
25+
if (!c) return;
26+
27+
pools.push(c);
28+
c.reset();
29+
}
30+
31+
static clear (): void {
32+
pools.length = 0;
33+
}
34+
}

cocos/physics-2d/box2d-wasm/physics-contact.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { Collider2D, Contact2DType, PhysicsSystem2D } from '../framework';
2929
import { B2Shape2D } from './shapes/shape-2d';
3030
import { IPhysics2DContact, IPhysics2DImpulse, IPhysics2DManifoldPoint, IPhysics2DWorldManifold } from '../spec/i-physics-contact';
3131

32-
const pools: PhysicsContact[] = [];
32+
/* pools moved to PhysicsContactManager */
3333

3434
// temp world manifold
3535
const pointCache = [new Vec2(), new Vec2()];
@@ -62,24 +62,7 @@ const impulse: IPhysics2DImpulse = {
6262

6363
/** @mangle */
6464
export class PhysicsContact implements IPhysics2DContact {
65-
static get (b2contact: number): PhysicsContact {
66-
let c = pools.pop();
67-
68-
if (!c) {
69-
c = new PhysicsContact();
70-
}
71-
72-
c.init(b2contact);
73-
return c;
74-
}
75-
76-
static put (b2contact: number): void {
77-
const c = getTSObjectFromWASMObjectPtr<PhysicsContact>(B2ObjectType.Contact, b2contact);
78-
if (!c) return;
79-
80-
pools.push(c);
81-
c.reset();
82-
}
65+
/* static get/put/clear moved to PhysicsContactManager */
8366

8467
colliderA: Collider2D | null = null;
8568
colliderB: Collider2D | null = null;

cocos/physics-2d/box2d-wasm/physics-world.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import { B2RigidBody2D } from './rigid-body';
3535
import { PhysicsContactListener } from './platform/physics-contact-listener';
3636
import { PhysicsAABBQueryCallback } from './platform/physics-aabb-query-callback';
3737
import { PhysicsRayCastCallback } from './platform/physics-ray-cast-callback';
38-
import { PhysicsContact } from './physics-contact';
38+
import { PhysicsContactManager } from './physics-contact-manager';
3939
import { Contact2DType, Collider2D, RaycastResult2D } from '../framework';
4040
import { B2Shape2D } from './shapes/shape-2d';
4141
import { PhysicsDebugDraw } from './platform/physics-debug-draw';
@@ -437,22 +437,22 @@ export class B2PhysicsWorld implements IPhysicsWorld {
437437
}
438438

439439
_onBeginContact (b2contact: number): void {
440-
const c = PhysicsContact.get(b2contact);
440+
const c = PhysicsContactManager.get(b2contact);
441441
c.emit(Contact2DType.BEGIN_CONTACT);
442442
}
443443

444444
_onEndContact (b2contact: number): void {
445-
const c = getTSObjectFromWASMObjectPtr<PhysicsContact>(B2ObjectType.Contact, b2contact);
445+
const c = PhysicsContactManager.find(b2contact);
446446
if (!c) {
447447
return;
448448
}
449449
c.emit(Contact2DType.END_CONTACT);
450450

451-
PhysicsContact.put(b2contact);
451+
PhysicsContactManager.put(b2contact);
452452
}
453453

454454
_onPreSolve (b2contact: number): void {
455-
const c = getTSObjectFromWASMObjectPtr<PhysicsContact>(B2ObjectType.Contact, b2contact);
455+
const c = PhysicsContactManager.find(b2contact);
456456
if (!c) {
457457
return;
458458
}
@@ -461,7 +461,7 @@ export class B2PhysicsWorld implements IPhysicsWorld {
461461
}
462462

463463
_onPostSolve (b2contact: number, impulse: number): void {
464-
const c = getTSObjectFromWASMObjectPtr<PhysicsContact>(B2ObjectType.Contact, b2contact);
464+
const c = PhysicsContactManager.find(b2contact);
465465
if (!c) {
466466
return;
467467
}
@@ -471,4 +471,8 @@ export class B2PhysicsWorld implements IPhysicsWorld {
471471
c.emit(Contact2DType.POST_SOLVE);
472472
c._setImpulse(0);
473473
}
474+
475+
clearContacts (): void {
476+
PhysicsContactManager.clear();
477+
}
474478
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
Copyright (c) 2024 Xiamen Yaji Software Co., Ltd.
3+
4+
https://www.cocos.com/
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights to
9+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10+
of the Software, and to permit persons to whom the Software is furnished to do so,
11+
subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.
23+
*/
24+
import { PhysicsContact, b2ContactExtends } from './physics-contact';
25+
26+
const contactMap = new Map<b2ContactExtends, PhysicsContact>();
27+
const pools: PhysicsContact[] = [];
28+
29+
export class PhysicsContactManager {
30+
static get (b2contact: b2ContactExtends): PhysicsContact {
31+
let c = pools.pop();
32+
if (!c) {
33+
c = new PhysicsContact();
34+
}
35+
c.init(b2contact);
36+
contactMap.set(b2contact, c);
37+
return c;
38+
}
39+
40+
static find (b2contact: b2ContactExtends): PhysicsContact | null {
41+
return contactMap.get(b2contact) ?? null;
42+
}
43+
44+
static put (b2contact: b2ContactExtends): void {
45+
const c = contactMap.get(b2contact);
46+
if (!c) return;
47+
pools.push(c);
48+
c.reset();
49+
contactMap.delete(b2contact);
50+
}
51+
52+
static clear (): void {
53+
contactMap.clear();
54+
pools.length = 0;
55+
}
56+
}

cocos/physics-2d/box2d/physics-contact.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ export type b2ContactExtends = b2.Contact & {
3333
m_userData: any;
3434
}
3535

36-
const pools: PhysicsContact[] = [];
37-
3836
// temp world manifold
3937
const pointCache = [new Vec2(), new Vec2()];
4038

@@ -68,25 +66,6 @@ const impulse: IPhysics2DImpulse = {
6866

6967
/** @mangle */
7068
export class PhysicsContact implements IPhysics2DContact {
71-
static get (b2contact: b2ContactExtends): PhysicsContact {
72-
let c = pools.pop();
73-
74-
if (!c) {
75-
c = new PhysicsContact();
76-
}
77-
78-
c.init(b2contact);
79-
return c;
80-
}
81-
82-
static put (b2contact: b2ContactExtends): void {
83-
const c: PhysicsContact = b2contact.m_userData as PhysicsContact;
84-
if (!c) return;
85-
86-
pools.push(c);
87-
c.reset();
88-
}
89-
9069
colliderA: Collider2D | null = null;
9170
colliderB: Collider2D | null = null;
9271

@@ -111,7 +90,6 @@ export class PhysicsContact implements IPhysics2DContact {
11190
this._inverted = false;
11291

11392
this._b2contact = b2contact;
114-
b2contact.m_userData = this;
11593
}
11694

11795
reset (): void {
@@ -124,7 +102,6 @@ export class PhysicsContact implements IPhysics2DContact {
124102
this.disabled = false;
125103
this._impulse = null;
126104

127-
this._b2contact!.m_userData = null;
128105
this._b2contact = null;
129106
}
130107

cocos/physics-2d/box2d/physics-world.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { PhysicsDebugDraw } from './platform/physics-debug-draw';
3939
import { Node, find, Layers } from '../../scene-graph';
4040
import { director } from '../../game';
4141
import type { Graphics } from '../../2d/components/graphics';
42+
import { PhysicsContactManager } from './physics-contact-manager';
4243

4344
const tempVec3 = new Vec3();
4445
const tempVec2_1 = new Vec2();
@@ -414,22 +415,22 @@ export class b2PhysicsWorld implements IPhysicsWorld {
414415
}
415416

416417
_onBeginContact (b2contact: b2ContactExtends): void {
417-
const c = PhysicsContact.get(b2contact);
418+
const c = PhysicsContactManager.get(b2contact);
418419
c.emit(Contact2DType.BEGIN_CONTACT);
419420
}
420421

421422
_onEndContact (b2contact: b2ContactExtends): void {
422-
const c = b2contact.m_userData as PhysicsContact;
423+
const c = PhysicsContactManager.find(b2contact);
423424
if (!c) {
424425
return;
425426
}
426427
c.emit(Contact2DType.END_CONTACT);
427428

428-
PhysicsContact.put(b2contact);
429+
PhysicsContactManager.put(b2contact);
429430
}
430431

431432
_onPreSolve (b2contact: b2ContactExtends): void {
432-
const c = b2contact.m_userData as PhysicsContact;
433+
const c = PhysicsContactManager.find(b2contact);
433434
if (!c) {
434435
return;
435436
}
@@ -438,7 +439,7 @@ export class b2PhysicsWorld implements IPhysicsWorld {
438439
}
439440

440441
_onPostSolve (b2contact: b2ContactExtends, impulse: b2.ContactImpulse): void {
441-
const c: PhysicsContact = b2contact.m_userData as PhysicsContact;
442+
const c = PhysicsContactManager.find(b2contact);
442443
if (!c) {
443444
return;
444445
}
@@ -448,4 +449,7 @@ export class b2PhysicsWorld implements IPhysicsWorld {
448449
c.emit(Contact2DType.POST_SOLVE);
449450
c._setImpulse(null);
450451
}
452+
clearContacts (): void {
453+
PhysicsContactManager.clear();
454+
}
451455
}

cocos/physics-2d/builtin/builtin-world.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,6 @@ export class BuiltinPhysicsWorld implements IPhysicsWorld {
285285
raycast (p1: IVec2Like, p2: IVec2Like, type: ERaycast2DType): RaycastResult2D[] {
286286
return [];
287287
}
288+
clearContacts (): void {
289+
}
288290
}

cocos/physics-2d/framework/physics-selector.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ const ENTIRE_WORLD: IPhysicsWorld = {
165165
testPoint: FUNC,
166166
testAABB: FUNC,
167167
drawDebug: FUNC,
168+
clearContacts: FUNC,
168169
};
169170

170171
export function checkPhysicsModule (obj: any): boolean {

cocos/physics-2d/framework/physics-system.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,12 @@ export class PhysicsSystem2D extends Eventify(System) {
381381
static constructAndRegister (): void {
382382
director.registerSystem(PhysicsSystem2D.ID, PhysicsSystem2D.instance, SystemPriority.LOW);
383383
}
384+
clearContacts (): void {
385+
this.physicsWorld.clearContacts();
386+
}
384387
}
385388

386389
if (!BUILD || !LOAD_BOX2D_MANUALLY) {
387390
director.once(DirectorEvent.INIT, (): void => { PhysicsSystem2D.constructAndRegister(); });
391+
director.once(DirectorEvent.RESET, (): void => { PhysicsSystem2D.instance.clearContacts(); });
388392
}

0 commit comments

Comments
 (0)