Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect Final face of DiceD8 #12

Open
kerorojason opened this issue Jul 11, 2019 · 7 comments
Open

Incorrect Final face of DiceD8 #12

kerorojason opened this issue Jul 11, 2019 · 7 comments

Comments

@kerorojason
Copy link

kerorojason commented Jul 11, 2019

[Update]
I changed the stableCount threshold in dice.js and the problem with DiceD6 is solved.
However, it still occurs with DiceD8 DiceD10 DiceD12 DiceD20😫


In my app, I sometimes got wrong face when the rolling animation ended.
I have changed some parameter (gravity, time-step and size).
However, the faces show incorrectly even though I set back to the same parameter as the example code.

   // CUSTOM
  world = new CANNON.World();
  world.gravity.set(0, -15.82 * 20, 0);
  world.broadphase = new CANNON.NaiveBroadphase();
  world.solver.iterations = 16;
  DiceManager.setWorld(world);
function updatePhysics() {
  world.step(2.0 / 60.0);
  for (var i in dice) {
    dice[i].updateMeshFromBody();
  }
}

Another possible reason I can think of is the animation function.
In order to reduce the FPS, I set the threshold to 1/30 so my updatePhysics() is called less frequently.
Could this cause the problem?

function animate() {
  let delta = clock.getDelta();
  deltaSum += delta;

  if (deltaSum > interval) {
    if (state === "jumping") {
      if (delta) {
        Cubemixer.update(delta);
      }
    } else if (state === "dicing") {
      updatePhysics();
    }
    renderer.render(scene, camera);
    stats.update();
    deltaSum %= interval;
    requestAnimationFrame(animate);
  } else {
    requestAnimationFrame(animate);
  }
}
@kerorojason kerorojason changed the title Incorrect Final face of DiceD6 Incorrect Final face of DiceD8 Jul 11, 2019
@eipporko
Copy link

eipporko commented Apr 25, 2021

I found the same issue and seems to be related with the method getUpsideValue(), for some reason sometimes the face detected by this method is wrong and because of that the shift done in the faces are wrong too. Showing an unexpected value in the dice.

I don't know if maybe this method is called some earlier been finished the simulation done, computing the getUpsideValue() on a still in movement die.

@eipporko
Copy link

I was doing some debugging inside getUpsideValue() and I found that the quaternion applied in the method to get the upside value sometimes differs between the simulation and the animation. I uploaded some screenshots and a video from my debugging enviroment. In red you can find the simulation estimation and in pink the final result after the animation it's finished, as I said sometimes fits perfectly ... sometimes doesn't :(

So, maybe is something related with the way the simulation is done or something inside CannonJS.

https://user-images.githubusercontent.com/2479373/116387376-0bc56000-a81b-11eb-97bd-63f20076e04e.mp4
Captura de pantalla de 2021-04-28 12-01-22
Captura de pantalla de 2021-04-28 12-01-34

@byWulf
Copy link
Owner

byWulf commented Apr 28, 2021

Hey guys :) Thanks for looking into the problem! Unfortunately I currently don't have any time for the project, so I would be very happy if you find out the cause..

I noticed it back in the days as I made this package, but only sometimes.. It could be, that it has something to do with finding out, when the die finished rolling. If I remember correctly, I have a threshold of frames. If the die doesn't move too much in this threshold, the system takes it as "rolling finished" and switches the sides. Now it could be, that it was just on the edge, but eventually rolled more after this "slowness". And this of course mixes up the sides...

@eipporko
Copy link

In first place I thought that could be something related with not finding correctly when the die was not rolling. But I think that is something more related with the inner working of CannonJS rather than the die is moving a little bit more. Seems that sometimes the trajectory is completely different.

@eipporko
Copy link

eipporko commented Apr 29, 2021

Ok, I was modifying a little bit the library to be sure that this bug was not related with the method to known when the die stops rolling. And I'm 100% that it's something related with the way how CannonJS resolves the collisions.

I don't know why, because seems to be using a fixed-step simulation, and all the rolls would have to be the same, as long as they are using the same parameters to roll the dice (position, quaternion, velocity, angularVelocity...) but sometimes this think fails . :(

Now it shows both dice rolls, the first one used to discover the upside value and the second one is the simulation showed. In most of the cases uses to fits, but when appears a discrepancy between them, is easy to see that the dices follow different paths, so it was solved in a different way.

You can find wrong dice rolls in the video attached below:

  • (00:49)
  • (01:05)
  • (01:30)
  • (02:02)
debug_2.mp4

@eipporko
Copy link

eipporko commented Apr 29, 2021

Ok, I think I found the bug. It is related to the fact that the body is reused for both the simulation and the final animation. Internally, the body class has some attributes (inertia, torque, force ...) that must always be the same if you expect to have two throws being identical. Now it was accumulating an error internally in the body and because of that the differences.

I looked in the CannonJS documentation to see if there was any method in the Body class to restore this class , but found nothing. So I created a method that does this task and is called before the second roll of the dice.

And need to be called also in the test rolling because the dice are being reused also.

    resetBody() {
          this.object.body.vlambda = new CANNON.Vec3();
      	  //this.object.body.collisionResponse = true;
          this.object.body.position = new CANNON.Vec3();
          this.object.body.previousPosition = new CANNON.Vec3();
          this.object.body.initPosition = new CANNON.Vec3();
          this.object.body.velocity = new CANNON.Vec3();
          this.object.body.initVelocity = new CANNON.Vec3();
          this.object.body.force = new CANNON.Vec3();
          //this.object.body.sleepState = 0;
          //this.object.body.timeLastSleepy = 0;
          //this.object.body._wakeUpAfterNarrowphase = false;
          this.object.body.torque = new CANNON.Vec3();
          this.object.body.quaternion = new CANNON.Quaternion();
          this.object.body.initQuaternion = new CANNON.Quaternion();
          this.object.body.angularVelocity = new CANNON.Vec3();
          this.object.body.initAngularVelocity = new CANNON.Vec3();
          this.object.body.interpolatedPosition = new CANNON.Vec3();
          this.object.body.interpolatedQuaternion = new CANNON.Quaternion();
          this.object.body.inertia = new CANNON.Vec3();
          this.object.body.invInertia = new CANNON.Vec3();
          this.object.body.invInertiaWorld = new CANNON.Mat3();
          //this.object.body.invMassSolve = 0;
          this.object.body.invInertiaSolve = new CANNON.Vec3();
          this.object.body.invInertiaWorldSolve = new CANNON.Mat3();
          //this.object.body.aabb = new CANNON.AABB();
          //this.object.body.aabbNeedsUpdate = true;
          this.object.body.wlambda = new CANNON.Vec3();

          this.object.body.updateMassProperties();
    }

The line which are under a comment are the ones that I found that have no interest in being reset. There are probably more, but now it's working.

I am going to prepare a pull request together with the BufferGeometry update, but I would need the documentation to be updated to know the process to test the module with typescript since I have no experience with that part and I don't know how to test it.

byWulf added a commit that referenced this issue Sep 23, 2021
Bump three to 0.131.0, Buffer Geometry,  Incorrect final face & D4 Material (Issues #6 #12 #19 )
@byWulf
Copy link
Owner

byWulf commented Sep 23, 2021

Please try it out, I just merged @eipporko 's PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants