using PhysxJS without webpack -- no collision physics working

I'm trying to get physx[js] to work without Webpack or any local servers etc, based on the example.

Everything seems to be loading, I'm even using their scripts from their server, all I did was copy the functions from the other web-pack files into a single html file to be used together, but when the page loads and everything happens, the items fall right through the ground and no callback collision functions are called.

Here's the code, with three.min.js as the only dependency

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/physx-js/dist/physx.release.js"></script>
<script>
let loaded = false
let cb = null
let physics
let scene
let bodies = {}

    PhysX = PHYSX({
        locateFile(path) {
            if (path.endsWith('.wasm')) {
                return "https://cdn.jsdelivr.net/npm/physx-js/dist/physx.release.wasm"
            }
            return path
        },
        onRuntimeInitialized() {
            loaded = true
            console.log('PhysX loaded')
            setup()
            if (cb) cb()
        },
    })
        
//  })
    
const onLoad = _cb => {
  cb = _cb
  if (loaded) cb()
}

const setup = () => {
  const version = PhysX.PX_PHYSICS_VERSION
  const defaultErrorCallback = new PhysX.PxDefaultErrorCallback()
  const allocator = new PhysX.PxDefaultAllocator()
  const foundation = PhysX.PxCreateFoundation(
    version,
    allocator,
    defaultErrorCallback
  )
  const triggerCallback = {
    onContactBegin: () => {},
    onContactEnd: () => {},
    onContactPersist: () => {},
    onTriggerBegin: () => {},
    onTriggerEnd: () => {},
  }
  const physxSimulationCallbackInstance = PhysX.PxSimulationEventCallback.implement(
    triggerCallback
  )

  physics = PhysX.PxCreatePhysics(
    version,
    foundation,
    new PhysX.PxTolerancesScale(),
    false,
    null
  )
  PhysX.PxInitExtensions(physics, null)
  const sceneDesc = PhysX.getDefaultSceneDesc(
    physics.getTolerancesScale(),
    0,
    physxSimulationCallbackInstance
  )
  scene = physics.createScene(sceneDesc)
}

const init = entities => {
  entities.forEach(entity => {
    let geometry
    if (entity.body.type === 'box') {
      geometry = new PhysX.PxBoxGeometry(
        // PhysX uses half-extents
        entity.body.size[0] / 2,
        entity.body.size[1] / 2,
        entity.body.size[2] / 2
      )
    }
    if (entity.body.type === 'spehre') {
      geometry = new Physx.PxSphereGeometry(...entity.body.size)
    }
    const material = physics.createMaterial(0.2, 0.2, 0.2)
    const flags = new PhysX.PxShapeFlags(
      PhysX.PxShapeFlag.eSCENE_QUERY_SHAPE.value |
        PhysX.PxShapeFlag.eSIMULATION_SHAPE.value
    )
    const shape = physics.createShape(geometry, material, false, flags)
    const transform = {
      translation: {
        x: entity.transform.position[0],
        y: entity.transform.position[1],
        z: entity.transform.position[2],
      },
      rotation: {
        w: entity.transform.rotation[3], // PhysX uses WXYZ quaternions,
        x: entity.transform.rotation[0],
        y: entity.transform.rotation[1],
        z: entity.transform.rotation[2],
      },
    }
    let body
    if (entity.body.dynamic) {
      body = physics.createRigidDynamic(transform)
    } else {
      body = physics.createRigidStatic(transform)
    }
    body.attachShape(shape)
    bodies[entity.id] = body
    scene.addActor(body, null)
  })
}

const update = entities => {
  scene.simulate(1 / 60, true)
  scene.fetchResults(true)
  entities.forEach(entity => {
    const body = bodies[entity.id]
    const transform = body.getGlobalPose()
    entity.transform.position[0] = transform.translation.x
    entity.transform.position[1] = transform.translation.y
    entity.transform.position[2] = transform.translation.z
    entity.transform.rotation[0] = transform.rotation.x
    entity.transform.rotation[1] = transform.rotation.y
    entity.transform.rotation[2] = transform.rotation.z
    entity.transform.rotation[3] = transform.rotation.w
  })
}









const container = document.createElement('div')
container.style.position = 'fixed'
container.style.top = '0'
container.style.left = '0'
container.style.right = '0'
container.style.bottom = '0'
document.body.appendChild(container)

const sceneT = new THREE.Scene()
sceneT.background = new THREE.Color('white')

const dirLight = new THREE.DirectionalLight('white', 0.8)
dirLight.position.set(-1, 1.75, 1)
dirLight.position.multiplyScalar(30)
dirLight.castShadow = true
dirLight.shadow.mapSize.width = 1024
dirLight.shadow.mapSize.height = 1024
sceneT.add(dirLight)

const light = new THREE.AmbientLight('white', 0.3)
sceneT.add(light)

const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
)
camera.position.fromArray([
  -0.4013406342550598,
  7.44362999004455,
  11.24080658033156,
])
camera.quaternion.fromArray([
  -0.28811373671368645,
  -0.017086547783363,
  -0.005141753910019259,
  0.9574299384124418,
])

const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true

container.appendChild(renderer.domElement)

const meshes = {}

const initT = entities => {
  entities.forEach(entity => {
    let geometry
    if (entity.model.type === 'box') {
      geometry = new THREE.BoxGeometry(
        entity.model.size[0],
        entity.model.size[1],
        entity.model.size[2]
      )
    }
    const material = new THREE.MeshStandardMaterial({ color: '#65C7F1' })
    const mesh = new THREE.Mesh(geometry, material)
    mesh.position.fromArray(entity.transform.position)
    mesh.quaternion.fromArray(entity.transform.rotation)
    mesh.castShadow = true
    mesh.receiveShadow = true
    meshes[entity.id] = mesh
    sceneT.add(mesh)
  })
}

const updateT = entities => {
  entities.forEach(entity => {
    const mesh = meshes[entity.id]
    mesh.position.fromArray(entity.transform.position)
    mesh.quaternion.fromArray(entity.transform.rotation)
  })
  renderer.render(sceneT, camera)
}








let tick = 0

const entitiess = makeEntities()

const updateH = () => {
  tick++
  update(entitiess)
  updateT(entitiess)
  // if (tick >= 200) return // DEBUG: only run a few ticks then stop
  requestAnimationFrame(updateH)
}

onLoad(() => {
  init(entitiess)
  initT(entitiess)
  updateH()
})

    
function makeEntities ()  {
  let ids = 0
  const entities = []

  entities.push({
    id: ++ids,
    transform: {
      position: [0, 0, 0],
      rotation: [0, 0, 0, 1],
    },
    model: {
      type: 'box',
      size: [10, 0.1, 10],
    },
    body: {
      type: 'box',
      size: [10, 0.1, 10],
      dynamic: false,
    },
  })

  for (let i = 0; i < 5; i++) {
    for (let j = 0; j < 5; j++) {
        
      entities.push({
        id: ++ids,
        transform: {
          position: [
            -2.5 + i + 0.1 * i,
            Math.floor(Math.random() * 6) + 1,
            -2.5 + j + 0.1 * j,
          ],
          rotation: [0, 0, 0.3, 0.7],
        },
        model: {
          type: 'box',
          size: [1, 1, 1],
        },
        body: {
          type: 'box',
          size: [1, 1, 1],
          dynamic: true,
        },
      })
    }
  }

  return entities
}
</script>

Tried various ways of using the code in this way, doesn't work, even though when downloading the example and using nodejs and webpack with almost the same code it does work, as well as the example file testing online also works, any ideas?!

Upvotes: 1

Views: 133

Answers (0)

Related Questions