Created
July 12, 2021 08:40
-
-
Save Sumechoo/4c6515d8825c2b7e0bb8e8c1619657fa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createContext, FC, useEffect, useState } from "react"; | |
import Ammo from 'ammojs-typed'; | |
import * as THREE from 'three'; | |
import { useFrame } from "@react-three/fiber"; | |
const clock = new THREE.Clock(true); | |
const createWorld = async () => { | |
const api = await Ammo(); | |
const collisionConfiguration = new api.btDefaultCollisionConfiguration(); | |
const dispatcher = new api.btCollisionDispatcher( collisionConfiguration ); | |
const broadphase = new api.btDbvtBroadphase(); | |
const solver = new api.btSequentialImpulseConstraintSolver(); | |
const world = new api.btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); | |
world.setGravity( new api.btVector3( 0, -9.82, 0 ) ); | |
console.info('creating world'); | |
return world; | |
} | |
interface AmmoContextValue { | |
world: Ammo.btDiscreteDynamicsWorld; | |
} | |
export const AmmoPhysicsContext = createContext<null | AmmoContextValue>(null); | |
export const AmmoPhysics: FC = ({ children }) => { | |
const [contextValue, setContextValue] = useState<AmmoContextValue | null>(null); | |
useFrame(() => { | |
if (contextValue) { | |
contextValue.world.stepSimulation(clock.getDelta(), 10); | |
} | |
}) | |
useEffect(() => { | |
createWorld() | |
.then((world) => { | |
setContextValue({world}); | |
}); | |
}, []); | |
if (!contextValue) { | |
return null; | |
} | |
return ( | |
<AmmoPhysicsContext.Provider value={contextValue}> | |
{children} | |
</AmmoPhysicsContext.Provider> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { GameInstance } from "../../core/types"; | |
import { AmmoPhysics } from "../../core/Ammo/AmmoPhysics"; | |
import { FC } from "react"; | |
import { useRigidbody } from "../../core/Ammo/hooks/useRigidbody"; | |
const AmmoCube: FC = () => { | |
const [ref] = useRigidbody(); | |
return ( | |
<mesh | |
ref={ref} | |
> | |
<boxGeometry /> | |
<meshBasicMaterial color='red' /> | |
</mesh> | |
) | |
} | |
export const AmmoPlayground: GameInstance = { | |
Ui: () => null, | |
Game: () => { | |
return ( | |
<AmmoPhysics> | |
<AmmoCube /> | |
<AmmoCube /> | |
</AmmoPhysics> | |
) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useFrame } from "@react-three/fiber"; | |
import { useContext, useEffect, useRef, useState } from "react" | |
import * as THREE from 'three'; | |
import Ammo from 'ammojs-typed'; | |
import { AmmoPhysicsContext } from "../AmmoPhysics"; | |
export const useRigidbody = () => { | |
const ref = useRef(new THREE.Object3D()); | |
const [rbReference, setRbReference] = useState<Ammo.btRigidBody | null>(null); | |
const context = useContext(AmmoPhysicsContext); | |
useFrame(() => { | |
const motionState = rbReference?.getMotionState(); | |
if (motionState) { | |
Ammo().then((api) => { | |
let TRANSFORM_AUX = new api.btTransform(); | |
motionState.getWorldTransform(TRANSFORM_AUX); | |
var p = TRANSFORM_AUX.getOrigin(); | |
var q = TRANSFORM_AUX.getRotation(); | |
ref.current.position.set(p.x(), p.y(), p.z()); | |
}); | |
} | |
}); | |
useEffect(() => { | |
if (rbReference === null && context) { | |
Ammo().then((api) => { | |
const mass = 1; | |
const tempVec = new api.btVector3(2,2,2); | |
const geometry = new api.btBoxShape(tempVec); | |
const transform = new api.btTransform(); | |
transform.setIdentity(); | |
transform.setOrigin(new api.btVector3(0,10,0)); | |
transform.setRotation(new api.btQuaternion(0,0,0,0)); | |
const motionState = new api.btDefaultMotionState(transform); | |
const localInertia = new api.btVector3(0,0,0); | |
geometry.calculateLocalInertia(mass, localInertia); | |
const rbConstructionInfo = new api.btRigidBodyConstructionInfo(mass, motionState, geometry, localInertia); | |
const rigidbody = new api.btRigidBody(rbConstructionInfo); | |
rigidbody.setActivationState(4); | |
rigidbody.setFriction(1); | |
rigidbody.setLinearVelocity(new api.btVector3(1,0,0)); | |
context.world.addRigidBody(rigidbody); | |
setRbReference(rigidbody); | |
console.info('creating and adding rigidbody here', rigidbody); | |
}); | |
} | |
}, [context, rbReference]); | |
return [ref]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment