Hi all,
I need to let the user to customize a cube's textures. A typical scenario is as the following:
1) My system renders a cube with default textures for the cube's six surfaces.
2) The user clicks on a surfaces.
3) A pop-up menu appears and let the user to choose a local texture file.
4) My system renders the clicked cube surface with the new texture.
I know how to decide whether the cube has been clicked on by functions within collision manager.
The problem is how to determine which surface the user has picked.
Any ideas?
Thanks.
How to know which surface of a cube has been clicked on?
Can you get the normal of the surface clicked on? You can get a triangle3df which i think has normal information, is there someway you could use the normal of the surface to decide which side it was?
Or alternatively presumably you have the 6 sides of the cube somehow seperate so maybe you could compare the position of the intersection from the click with the bounding boxes around the sides of the cubes?
Or alternatively presumably you have the 6 sides of the cube somehow seperate so maybe you could compare the position of the intersection from the click with the bounding boxes around the sides of the cubes?
You should be able to get access to the mesh for the cube. Access the mesh of the object, and check to see if the ray intersects the mesh bounding box. If it does, then you iterate over each mesh buffer to see if the ray intersects the front face of each triangle in the mesh buffer. If it does, then you know the mesh buffer that has been intersected. This is the mesh buffer that you want to change the material of.
Travis
Travis
Thank you guys for these quick replies.
What I did was to combine your suggestions together:
1) find the triangle that the mouse clicks on by casting a ray from the mouse 's 2D screen coordinate using collisionManager->getCollisionPoint() method.
2) Using the same ray to get which scene node has been clicked on, collisionManager->getSceneNodeFromRayBB().
3) Traverse through mesh buffers of the clicked scene node and compare its surface normal with that of the clicked triangle to determine which surface has been clicked.
It works like a charm.
Thanks a lot.
What I did was to combine your suggestions together:
1) find the triangle that the mouse clicks on by casting a ray from the mouse 's 2D screen coordinate using collisionManager->getCollisionPoint() method.
2) Using the same ray to get which scene node has been clicked on, collisionManager->getSceneNodeFromRayBB().
3) Traverse through mesh buffers of the clicked scene node and compare its surface normal with that of the clicked triangle to determine which surface has been clicked.
It works like a charm.
Thanks a lot.
Thinking about it i reckon you need to check more than the normal...
With a simple cube it's fine as there are 6 normals and each face has one of them meaning there are no 2 faces with the same normal.
But if you then want to move onto more complicated shapes there could be two faces with the same normal and with your current method you may change the material of the wrong one. So i guess you should check that the vertex indices or vertex positions of the hit triangle are the same as the one you've found in the mesh buffer too.
With a simple cube it's fine as there are 6 normals and each face has one of them meaning there are no 2 faces with the same normal.
But if you then want to move onto more complicated shapes there could be two faces with the same normal and with your current method you may change the material of the wrong one. So i guess you should check that the vertex indices or vertex positions of the hit triangle are the same as the one you've found in the mesh buffer too.
Re:
Hi! Here's my idea:
1. If you place the surfaces (2 or more triangles) that have the same triangle normals (this content will be a "side" of the mesh) and put these into 1 meshbuffer, then you have a side.
It's good, because you can change it's texture with one call. Also, it's good because you know that this was the "right" side of your mesh, for example (so it'll be easy to identify which "side" was hit by it's meshbuffer index).
You should make all the "sides" (= meshbuffers) this way, and add all of these to a mesh. In your case, this mesh will be the cube.
2. Project the ray from screen coordinates, define the ray's length.
3. The collision part: Cycle through every meshbuffers (and cycle through every triangle of the current meshbuffer) and check with a ray-collision function to decide:
- if there was collision at all,
- which triangle,
- and which "side" (= meshbuffer) was hit = what it's index,
This last one is what you're interested in.
4. Select the closest (to the ray.Start) of these hits, that'll tell you which "side" was hit, which triangle of that side (= meshbuffer), exactly where it was hit, and even give you the index number of the meshbuffer -> so you can easily change it's texture.
Cheers,
PI
1. If you place the surfaces (2 or more triangles) that have the same triangle normals (this content will be a "side" of the mesh) and put these into 1 meshbuffer, then you have a side.
It's good, because you can change it's texture with one call. Also, it's good because you know that this was the "right" side of your mesh, for example (so it'll be easy to identify which "side" was hit by it's meshbuffer index).
You should make all the "sides" (= meshbuffers) this way, and add all of these to a mesh. In your case, this mesh will be the cube.
2. Project the ray from screen coordinates, define the ray's length.
3. The collision part: Cycle through every meshbuffers (and cycle through every triangle of the current meshbuffer) and check with a ray-collision function to decide:
- if there was collision at all,
- which triangle,
- and which "side" (= meshbuffer) was hit = what it's index,
This last one is what you're interested in.
4. Select the closest (to the ray.Start) of these hits, that'll tell you which "side" was hit, which triangle of that side (= meshbuffer), exactly where it was hit, and even give you the index number of the meshbuffer -> so you can easily change it's texture.
Cheers,
PI
i would just place 6 seperate quads (invisible SceneNodes) with an
id (back, front, left, right, top, bottom) infront of the original cube Node an attach the invisible quads as childs of the cube SceneNode. ... then you could use getSceneNodeFromRayBB()
or do I'm thinking wrong ?! Its simple isn't ?
id (back, front, left, right, top, bottom) infront of the original cube Node an attach the invisible quads as childs of the cube SceneNode. ... then you could use getSceneNodeFromRayBB()
or do I'm thinking wrong ?! Its simple isn't ?