Skip to content

Commit

Permalink
Add physicsMaterial loader and joint component parser and change radi…
Browse files Browse the repository at this point in the history
…ans to degrees in physics (#2475)

* feat: add physicsMaterial loader and joint component parser and change radians to degrees in physics
  • Loading branch information
luzhuang authored Dec 24, 2024
1 parent f5351a9 commit 90c3228
Show file tree
Hide file tree
Showing 27 changed files with 290 additions and 117 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/asset/AssetType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,7 @@ export enum AssetType {
/** AudioClip, include ogg, wav and mp3. */
Audio = "Audio",
/** Project asset. */
Project = "project"
Project = "project",
/** PhysicsMaterial. */
PhysicsMaterial = "PhysicsMaterial"
}
6 changes: 3 additions & 3 deletions packages/core/src/physics/CharacterController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class CharacterController extends Collider {
private _nonWalkableMode: ControllerNonWalkableMode = ControllerNonWalkableMode.PreventClimbing;
@deepClone
private _upDirection = new Vector3(0, 1, 0);
private _slopeLimit = 0.707;
private _slopeLimit = 45;

/**
* The step offset for the controller, the value must be greater than or equal to 0.
Expand Down Expand Up @@ -61,8 +61,8 @@ export class CharacterController extends Collider {
}

/**
* The slope limit for the controller, the value is the cosine value of the maximum slope angle.
* @defaultValue 0.707(the cosine value of 45 degrees)
* The slope limit in degrees for the controller, the value is the cosine value of the maximum slope angle.
* @defaultValue 45 degrees
*/
get slopeLimit(): number {
return this._slopeLimit;
Expand Down
21 changes: 18 additions & 3 deletions packages/core/src/physics/DynamicCollider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ export class DynamicCollider extends Collider {
private _centerOfMass = new Vector3();
@ignoreClone
private _inertiaTensor = new Vector3(1, 1, 1);
private _maxAngularVelocity = 100;
private _maxAngularVelocity = 18000 / Math.PI;
private _maxDepenetrationVelocity = 1.0000000331813535e32;
private _solverIterations = 4;
private _useGravity = true;
private _isKinematic = false;
private _constraints: DynamicColliderConstraints = 0;
private _collisionDetectionMode: CollisionDetectionMode = CollisionDetectionMode.Discrete;
Expand Down Expand Up @@ -77,7 +78,7 @@ export class DynamicCollider extends Collider {
}

/**
* The angular velocity vector of the dynamic collider measured in radians per second.
* The angular velocity vector of the dynamic collider measured in degrees per second.
*/
get angularVelocity(): Vector3 {
//@ts-ignore
Expand Down Expand Up @@ -185,7 +186,7 @@ export class DynamicCollider extends Collider {
}

/**
* The maximum angular velocity of the collider measured in radians per second. (Default 7) range { 0, infinity }.
* The maximum angular velocity of the collider measured in degrees per second.
*/
get maxAngularVelocity(): number {
return this._maxAngularVelocity;
Expand Down Expand Up @@ -240,6 +241,20 @@ export class DynamicCollider extends Collider {
}
}

/**
* Controls whether gravity affects the dynamic collider.
*/
get useGravity(): boolean {
return this._useGravity;
}

set useGravity(value: boolean) {
if (this._useGravity !== value) {
this._useGravity = value;
(<IDynamicCollider>this._nativeCollider).setUseGravity(value);
}
}

/**
* Controls whether physics affects the dynamic collider.
*/
Expand Down
37 changes: 24 additions & 13 deletions packages/core/src/physics/joint/Joint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { dependentComponents, DependentMode } from "../../ComponentsDependencies
import { Entity } from "../../Entity";
import { Collider } from "../Collider";
import { TransformModifyFlags } from "../../Transform";

import { DynamicCollider } from "../DynamicCollider";
/**
* A base class providing common functionality for joints.
* @decorator `@dependentComponents(Collider, DependentMode.CheckOnly)`
*/
@dependentComponents(Collider, DependentMode.CheckOnly)
@dependentComponents(DynamicCollider, DependentMode.AutoAdd)
export abstract class Joint extends Component {
private static _tempVector3 = new Vector3();

Expand All @@ -24,6 +24,8 @@ export abstract class Joint extends Component {
private _force = Infinity;
private _torque = Infinity;
private _automaticConnectedAnchor = true;
@ignoreClone
private _updateConnectedActualAnchor: Function;

/**
* The connected collider.
Expand All @@ -37,7 +39,7 @@ export abstract class Joint extends Component {
this._connectedColliderInfo.collider?.entity._updateFlagManager.removeListener(this._onConnectedTransformChanged);
value?.entity._updateFlagManager.addListener(this._onConnectedTransformChanged);
this._connectedColliderInfo.collider = value;
this._nativeJoint?.setConnectedCollider(value._nativeCollider);
this._nativeJoint?.setConnectedCollider(value?._nativeCollider);
if (this._automaticConnectedAnchor) {
this._calculateConnectedAnchor();
} else {
Expand All @@ -47,8 +49,7 @@ export abstract class Joint extends Component {
}

/**
* The connected anchor position.
* @remarks If connectedCollider is set, this anchor is relative offset, or the anchor is world position.
* The anchor position.
*/
get anchor(): Vector3 {
return this._colliderInfo.anchor;
Expand All @@ -66,13 +67,22 @@ export abstract class Joint extends Component {
/**
* The connected anchor position.
* @remarks If connectedCollider is set, this anchor is relative offset, or the anchor is world position.
* The connectedAnchor is automatically calculated, if you want to set it manually, please set automaticConnectedAnchor to false
*/
get connectedAnchor(): Vector3 {
return this._connectedColliderInfo.anchor;
const connectedColliderAnchor = this._connectedColliderInfo.anchor;
if (this._automaticConnectedAnchor) {
//@ts-ignore
connectedColliderAnchor._onValueChanged = null;
this._calculateConnectedAnchor();
//@ts-ignore
connectedColliderAnchor._onValueChanged = this._updateConnectedActualAnchor;
}
return connectedColliderAnchor;
}

set connectedAnchor(value: Vector3) {
if (this.automaticConnectedAnchor) {
if (this._automaticConnectedAnchor) {
console.warn("Cannot set connectedAnchor when automaticConnectedAnchor is true.");
return;
}
Expand All @@ -96,7 +106,7 @@ export abstract class Joint extends Component {
}

/**
* The scale to apply to the inverse mass of collider 0 for resolving this constraint.
* The scale to apply to the mass of collider 0 for resolving this constraint.
*/
get connectedMassScale(): number {
return this._connectedColliderInfo.massScale;
Expand All @@ -110,7 +120,7 @@ export abstract class Joint extends Component {
}

/**
* The scale to apply to the inverse mass of collider 1 for resolving this constraint.
* The scale to apply to the mass of collider 1 for resolving this constraint.
*/
get massScale(): number {
return this._colliderInfo.massScale;
Expand All @@ -124,7 +134,7 @@ export abstract class Joint extends Component {
}

/**
* The scale to apply to the inverse inertia of collider0 for resolving this constraint.
* The scale to apply to the inertia of collider0 for resolving this constraint.
*/
get connectedInertiaScale(): number {
return this._connectedColliderInfo.inertiaScale;
Expand All @@ -138,7 +148,7 @@ export abstract class Joint extends Component {
}

/**
* The scale to apply to the inverse inertia of collider1 for resolving this constraint.
* The scale to apply to the inertia of collider1 for resolving this constraint.
*/
get inertiaScale(): number {
return this._colliderInfo.inertiaScale;
Expand Down Expand Up @@ -183,8 +193,10 @@ export abstract class Joint extends Component {
super(entity);
//@ts-ignore
this._colliderInfo.anchor._onValueChanged = this._updateActualAnchor.bind(this, AnchorOwner.Self);
this._updateConnectedActualAnchor = this._updateActualAnchor.bind(this, AnchorOwner.Connected);
//@ts-ignore
this._connectedColliderInfo.anchor._onValueChanged = this._updateActualAnchor.bind(this, AnchorOwner.Connected);
this._connectedColliderInfo.anchor._onValueChanged = this._updateConnectedActualAnchor;

this._onSelfTransformChanged = this._onSelfTransformChanged.bind(this);
this._onConnectedTransformChanged = this._onConnectedTransformChanged.bind(this);
// @ts-ignore
Expand Down Expand Up @@ -261,7 +273,6 @@ export abstract class Joint extends Component {
}
}

@ignoreClone
private _updateActualAnchor(flag: AnchorOwner): void {
if (flag & AnchorOwner.Self) {
const worldScale = this.entity.transform.lossyWorldScale;
Expand Down
16 changes: 8 additions & 8 deletions packages/core/src/physics/joint/JointLimits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,34 @@ export class JointLimits {
private _damping = 0;

/**
* The upper angular limit (in radians) of the joint.
* The upper angular limit (in degrees) of the joint.
*/
get max(): number {
return this._max;
}

set max(value: number) {
if (value < this._min) {
throw new Error("Max limit must be greater than min limit");
}
if (this._max !== value) {
if (value < this._min) {
this._min = value;
}
this._max = value;
this._updateFlagManager.dispatch();
}
}

/**
* The lower angular limit (in radians) of the joint.
* The lower angular limit (in degrees) of the joint.
*/
get min(): number {
return this._min;
}

set min(value: number) {
if (value > this._max) {
throw new Error("Min limit must be less than max limit");
}
if (this._min !== value) {
if (value > this._max) {
this._max = value;
}
this._min = value;
this._updateFlagManager.dispatch();
}
Expand Down
24 changes: 16 additions & 8 deletions packages/core/src/physics/joint/JointMotor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ export class JointMotor {
}

set targetVelocity(value: number) {
this._targetVelocity = value;
this._updateFlagManager.dispatch();
if (this._targetVelocity !== value) {
this._targetVelocity = value;
this._updateFlagManager.dispatch();
}
}

/**
Expand All @@ -34,8 +36,10 @@ export class JointMotor {
}

set forceLimit(value: number) {
this._forceLimit = value;
this._updateFlagManager.dispatch();
if (this._forceLimit !== value) {
this._forceLimit = value;
this._updateFlagManager.dispatch();
}
}

/**
Expand All @@ -46,8 +50,10 @@ export class JointMotor {
}

set gearRatio(value: number) {
this._gearRatio = value;
this._updateFlagManager.dispatch();
if (this._gearRatio !== value) {
this._gearRatio = value;
this._updateFlagManager.dispatch();
}
}

/**
Expand All @@ -58,7 +64,9 @@ export class JointMotor {
}

set freeSpin(value: boolean) {
this._freeSpin = value;
this._updateFlagManager.dispatch();
if (this._freeSpin !== value) {
this._freeSpin = value;
this._updateFlagManager.dispatch();
}
}
}
7 changes: 5 additions & 2 deletions packages/core/src/physics/shape/ColliderShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,24 @@ export abstract class ColliderShape implements ICustomClone {
}

/**
* Physical material.
* Physical material, material can't be null.
*/
get material(): PhysicsMaterial {
return this._material;
}

set material(value: PhysicsMaterial) {
if (!value) {
throw new Error("The physics material of the shape can't be null.");
}
if (this._material !== value) {
this._material = value;
this._nativeShape.setMaterial(value._nativeMaterial);
}
}

/**
* The local rotation of this ColliderShape, in radians.
* The local rotation of this ColliderShape, in degrees.
*/
get rotation(): Vector3 {
return this._rotation;
Expand Down
2 changes: 1 addition & 1 deletion packages/design/src/physics/ICharacterController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export interface ICharacterController extends ICollider {
setUpDirection(up: Vector3): void;

/**
* Sets the slope limit.
* Sets the slope limit in degrees.
* @param slopeLimit The slope limit for the controller.
*/
setSlopeLimit(slopeLimit: number): void;
Expand Down
5 changes: 5 additions & 0 deletions packages/design/src/physics/IDynamicCollider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ export interface IDynamicCollider extends ICollider {
*/
setCollisionDetectionMode(value: number): void;

/**
* Whether the collider is affected by gravity.
*/
setUseGravity(value: boolean): void;

/**
* Controls whether physics affects the dynamic collider.
* @param value - is or not
Expand Down
33 changes: 33 additions & 0 deletions packages/loader/src/PhysicsMaterialLoader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
resourceLoader,
Loader,
AssetPromise,
AssetType,
LoadItem,
ResourceManager,
PhysicsMaterial
} from "@galacean/engine-core";

@resourceLoader(AssetType.PhysicsMaterial, ["mesh"])
class PhysicsMaterialLoader extends Loader<PhysicsMaterial> {
load(item: LoadItem, resourceManager: ResourceManager): AssetPromise<PhysicsMaterial> {
return (
resourceManager
// @ts-ignore
._request<any>(item.url, {
...item,
type: "json"
})
.then((data) => {
const physicsMaterial = new PhysicsMaterial();
physicsMaterial.bounciness = data.bounciness;
physicsMaterial.dynamicFriction = data.dynamicFriction;
physicsMaterial.staticFriction = data.staticFriction;
physicsMaterial.bounceCombine = data.bounceCombine;
physicsMaterial.frictionCombine = data.frictionCombine;

return physicsMaterial;
})
);
}
}
1 change: 1 addition & 0 deletions packages/loader/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import "./AudioLoader";
import "./ktx2/KTX2Loader";
import "./ShaderLoader";
import "./ShaderChunkLoader";
import "./PhysicsMaterialLoader";

export { GLTFLoader } from "./GLTFLoader";
export type { GLTFParams } from "./GLTFLoader";
Expand Down
Loading

0 comments on commit 90c3228

Please sign in to comment.