I am trying to create dice of different shapes - tetrahedron, cube and octahedron. I was able to get which side landed on top in a cube using the quaternion and figuring out certain patterns like this, this too although isnt perfect -
if (Math.abs(body.quaternion.y) < 0.00001) {
lastRoll += " 4 +";
presentScore += 4;
}
if (Math.abs(body.quaternion.x) < 0.00001) {
lastRoll += " 3 +";
presentScore += 3;
}
if (
body.quaternion.x.toString().substring(0, 5) ==
body.quaternion.y.toString().substring(1, 6)
) {
lastRoll += " 2 +";
presentScore += 2;
}
if (
body.quaternion.x.toString().substring(0, 5) ==
body.quaternion.y.toString().substring(0, 5)
) {
lastRoll += " 1 +";
presentScore += 1;
}
if (
body.quaternion.z.toString().substring(0, 5) ==
body.quaternion.y.toString().substring(1, 6)
) {
lastRoll += " 6 +";
presentScore += 6;
}
if (
body.quaternion.z.toString().substring(0, 5) ==
body.quaternion.y.toString().substring(0, 5)
) {
lastRoll += " 5 +";
presentScore += 5;
}
But this isnt working with my octahedron and tetrahedron dice. There are no constant quaternion patterns in those dice like in the cube dice. What can I do to do this? I did find an answer on stackoverflow for a similar queston but I am unable to recreate it with the octahedron and tetrahedron dice?
I would go the way, where I take the index of the side, whose normal’s dot product, in world coordinates, is closer to 1, against the up-vector (0, 1, 0).
Dot product in the docs: https://threejs.org/docs/index.html#api/en/math/Vector3.dot
2 Likes
An alternative is to cast a ray from the center upwards and the intersection will return which face is just above the center.
1 Like
AFAIK, die’s material needs to have side: THREE.DoubleSide
for that case. But yes, it’s an option too ![:slight_smile: :slight_smile:](https://emoji.discourse-cdn.com/twitter/slight_smile.png?v=12)
Maybe, to cast a ray from atop (put it high enough) towards the center of a die.
And also, in case of a cube, there is a very slight chance, when a ray goes in between two faces, thus there will be no intersection.
1 Like
@prisoner849, how can i get the individual side’s normal ?
The normal of any face, that belongs to the side, is the normal of the side ![:thinking: :thinking:](https://emoji.discourse-cdn.com/twitter/thinking.png?v=12)
@prisoner849, but how can I get each face’s normal ?
Any face consists of three vertices. The normal for any of these vertices is the normal of the face ![:thinking: :thinking:](https://emoji.discourse-cdn.com/twitter/thinking.png?v=12)
This works for BoxGeometry
and for other geometries, that extended from PolyhedronGeometry
.
Yes but how can I get the vertices of the individual faces of a cube made through boxgeometry like this -
let g = new THREE.BoxGeometry(2, 2, 2);
How can i iterate through the faces of the cube and get the vertices/ normal of each of the 6 faces of this cube to calculate the side of the cube which lands on the top ?
Specifically for BoxGeometry
you can iterate through g.attributes.normal
, getting data for every fourth vertex.
Some information about BufferGeometry
: How ot get vertices, faces, faceVertexUvs from bufferGeometry - #2 by prisoner849
@prisoner849, what about for Octahedron and Tetrahedron geometry ? How can i iterate through the faces of these shapes and get the vertices/ normal of each side from these shapes?
Their sides are triangles. So, how many vertices per side do they have?
I recommend to investigate the source code of VertexNormalHelper
.
It contains the code of the iterating through attributes.
@prisoner849, I think the octahedron will have 3 vertices per side. Thus I have used this -
let normals = body.geometry.attributes.normal.array
let maxArray = []
const a = new THREE.Vector3(0, 1, 0)
for (let i = 0; i < normals.length; i += 9) {
let vec = new THREE.Vector3(normals[i], normals[i + 3], normals[i + 3])
console.log(vec)
let dotProduct = vec.dot(a)
maxArray.push(dotProduct)
}
The problem I am facing now is that multiple sides have the exact same values vertices like this -
![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/c/e/ce5516e78e2ccad8d22e5d1681a2d7f5fe38ef7a.png)
Looks like you didn’t see the source code of that helper. Please, try to do it.
BufferAttribute has many useful properties and methods. .count
, for example.
Also, Vector3
has .fromBufferAttribute
method.