Search code examples
javaandroidarcoresceneform

How can I force objects to snap to a grid?


I'm building a board game app using ARCore and Sceneform. My 3D models need to snap to a grid instead of being placed anywhere. Imagine a chess board.
How do I do that?

I copied the classes TransformableNode and TranslationController to modify them. In TranslationController, the coordinates are set in the variable desiredLocalPosition using Vector3.
To my understanding I should be able to do an integer division of the coordinates so that my objects can only jump a specific distance.

this.desiredLocalPosition = new Vector3(pose.tx(), pose.ty(), pose.tz());

float X = (int) (pose.tx()/0.05f) * 0.05f;
float Y = pose.ty(); //i don't care about vertical
float Z = (int) (pose.tz()/0.05f) * 0.05f;

this.desiredLocalPosition.set(X,Y,Z);

Sadly this only works while I'm dragging the objects and ignores it when they're actually placed.

Since I'm a student I'm pretty much a noob programmer though. Does someone have an idea?


Solution

  • It looks like your problem is that you've modified the TranslationController#onContinueTransformation() method but not the TranslationController#onEndTransformation() method.

    The onEndTransformation() method is responsible for setting a new anchor based on the last HitResult detected at the end of the drag gesture. The gridlocked position you're setting as you go in onContinueTransformation() is being overridden by this new anchor.

    Simply removing the logic in the onEndTransformation() method will enable the behaviour you're looking for.

    Answer relevant for sceneform-ux:1.5.1.

    P.S: A more workable solution to the boardgame experience you're trying to create may be to create the board as a grid of Nodes and attach the game piece to the closest eligible Node to the lastArHitResult in onEndTransformation(). This would give you the flexibility of defining whatever boardspace you wished and reusing the same custom TransformationController, as well as creating a better "snap-to-space" user experience that happens only at the end of their drag motion.