Skip to content

Performance issue debug #6

@skywalkershen

Description

@skywalkershen

Thank you again for this awesome library which helps me a lot.

I have an issue regarding using BVHEcctrl to build firstperson mode for config based indoor scene, yet performance issue exists and hampers the experience:

  • Suddenly stuck issue: the normal orbit mode works with high fps without BVHEcctrl colliding mechanism. Once I switched to firstPersonMode, the fps lowered a bit on entering first person view, by just looking around without moving, the fps is stable. Yet at the first time moving with keyboard, the render stops for 1-3 seconds depends on the complexity of the scene, then the fps is back to stable firstPersonMode fps(lower than orbit mode). And occasionally, the stuck happens randomly during navigation, currently I don't have clue for its trigger. I suspect whether it is triggered by collision detection with complicated bvh, yet with bvh helper on, sometimes it seems to be nothing colliding when the freeze happens.
  • Occasionally, when entering the scene, I found the key controls for moving get their directions wrong, like key w will move the capsule backward instead of expected forward direction. It looks like the wsad direction bind to fixed world direction instead of camera direction. By switching to other mode and switch back, the issue might be gone.

Sorry in advance since the logic and data are highly coupled with my database, I could not provide a repo to replicate the issue. Please see below for the description of my implementation.

I have config based template to build indoor scene, the root component looks like

root component

   // use modelConfig to pass config to customModel component which include **StaticCollider** and other process logic
   { modelConfigs.map((modelConfig) => (<Suspense key={model.id} fallback={null}>
          //
          <CustomModel
            config={modelConfig}
          >
    }
    // the FirstPersonControl component here includes control logic for first person mode built on BVHEcctrl, see below for detailed break down
    {mode === ModeType.FIRST_PERSON && <FirstPersonControl/>}

I'm using StaticCollider like the following in CustomModel component

<StaticCollider 
            key={`collider-${config.id}`}
            debug={false}
            bvhName={`bvh-${config.id}`}
            excludeFloatHit={true}
            BVHOptions={{
              strategy: SAH,
              verbose: false,
              setBoundingBox: true,
              maxDepth: 3,
              maxLeafTris: 10,
              indirect: false
            }}
          >

FirstPersonControl component

   export const FirstPersonControl = () => {

     useEffect(() => {
        calculateAndSetEntryPositionDirectionForCamera();
    }, []);
     
     const keyboardMap = [
        { name: "forward", keys: ["ArrowUp", "KeyW"] },
        { name: "backward", keys: ["ArrowDown", "KeyS"] },
        { name: "leftward", keys: ["ArrowLeft", "KeyA"] },
        { name: "rightward", keys: ["ArrowRight", "KeyD"] },
        { name: "jump", keys: ["Space"] },
        { name: "run", keys: ["Shift"] },
        { name: "action1", keys: ["1"] },
        { name: "action2", keys: ["2"] },
        { name: "action3", keys: ["3"] },
        { name: "action4", keys: ["KeyF"] },
    ];
 
      useFrame((state) => {
        // For camera control to follow character
        if (cameraControlRef.current && ecctrlRef.current) {
            if (ecctrlRef.current.group)
                cameraControlRef.current.moveTo(
                    ecctrlRef.current.group.position.x,
                    ecctrlRef.current.group.position.y + 0.5,
                    ecctrlRef.current.group.position.z,
                    true
                )

            // Hide character model if camera is too close
            if (characterModelRef.current) {
                if (cameraControlRef.current.distance < 0.7) {
                    characterModelRef.current.visible = false
                } else {
                    characterModelRef.current.visible = true
                }
            }
        }
    })
      return (
        <>  
            {/* <PerspectiveCamera makeDefault /> */}
            <CameraControls
                ref={cameraControlRef}
                smoothTime={0.1}
                colliderMeshes={colliderMeshesArray}
                // Disable zoom by setting min and max distance to the same value
                minDistance={0.01}
                maxDistance={0.01}
                makeDefault
            />
            {/* Keyboard preset */}
            <KeyboardControls map={keyboardMap} onChange={(name, pressed, state) => {
                keyDownOnChange?.(Object.keys(state).filter((key) => state[key]));
                console.log(name, pressed, state);
            }}>
                {/* Character Control */}
                <BVHEcctrl
                    ref={ecctrlRef}
                    colliderCapsuleArgs={[0.17, 1, 6, 8]}
                    jumpVel={2}
                    debug={false}
                    airDragFactor={0.2}
                />
            </KeyboardControls>
        </>
    );
   }

Sorry again for the trouble, I know it is cumbersome to debug only based on these abstracted description, yet it is quite unlikely I can decouple all those data and logic to make a repo to replicate the issue. Any thought or advice will be appreciated, hope you can take some time to look at the description above and shed some light upon the issue.

Thank you so much.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions