correct use of setDebugDataVisible

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
KevinCain
Posts: 18
Joined: Tue Aug 15, 2006 5:00 pm
Location: San Francisco

correct use of setDebugDataVisible

Post by KevinCain »

I'd like to toggle a bounding box on and off when a particular node is highlighted in the editor I'm writing. In the small excerpt below, I'm using 'getSceneNodeFromId' to access a given node, and 'setDebugDataVisible' to toggle that node's visibility based on a bitmask. I also turn real lighting on and off for the node as a simple way to change the node color while it is selected.

Code: Select all

              for(int i=0; i<num_seg; ++i) {

                scene::ISceneNode* theNode = m_smgr->getSceneNodeFromId((tm_obj_id*100)+i);

                if( tm.flags & 0x2 ) {
                  theNode->setDebugDataVisible(1); // Draw a bounding box around the node's mesh
                  theNode->setMaterialFlag   ( video::EMF_LIGHTING, false);  //highlight
                } else {
                  theNode->setDebugDataVisible(0); // Remove bounding box around the node's mesh
                  theNode->setMaterialFlag   ( video::EMF_LIGHTING, true);  //remove highlight
                }
              }
This code works in most cases--creating a bounding box and chaning the node's lighting.

However, in some cases the bounding box does not appear. I'm not doing anything exotic when setting the ID, I don't think--that code is here:

Code: Select all

            irr::scene::IMeshSceneNode* node  = m_smgr->addMeshSceneNode(mesh);
            int node_seg_id = (tm_id * 100) + i;
            node->setID(node_seg_id);  // assign an Irrlicht-compliant ID for each node
Interestingly, the EMF_LIGHTING change always happens correctly (i.e., to the correct node in the editor), so it's not a simple matter of asking for the wrong or nonexistent node.

All I can think of is parenting -- would parenting a node after setting an ID have any impact on displaying its bounding box?

Many thanks for any advice.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Hmm, I remember a problem someone had with collision:
He couldn't get a collision rsponse from a node by using it's bounding box...
The problem was with the mesh itself (and maybe a bug in the mesh loader)...
It was that the bounding box was not created correctly, it had a size of 0 in Y direction, so in fact there was no BB !!!
After re-exporting the mesh with Milkshape it worked like a charm...

Maybe this is happening also to you ???
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
KevinCain
Posts: 18
Joined: Tue Aug 15, 2006 5:00 pm
Location: San Francisco

Thanks, Acki

Post by KevinCain »

Thanks for your reply -- a good suggestion.

I'm actually able to do collision with these meshes, even the ones I can't see a bounding box for. Both bounding box and fine selectors are both working for my meshes, so I'm able to perform picking etc. but again I'm not to see the bounding box. Very strange!

It's a simple thing, I'm sure. Here's the trick:

1. In the code fragment below, I have a loop that creates cylinder segments between n "keypoints" in the data structure 'tm'. The result is a string of cylinders that are connected.

2. If we only go through the loop once (just two keypoints at either end of a cylinder) then the mesh created is quite happy to display its bounding box with the above code (see the code fragment in my above post).

3. However, if we go through the loop more than once (more than two keypoints, creating more than one cylinder segment), then everything else works fine but I'm not able to see the bounding boxes for the cylinder meshes when they're called for (again, see the code fragment in my above post)

Again, in either case the selector assignment is working fine, and I can toggle lighting for the meshes -- I just can't see a bounding box. ;-)

I have the suspicious that the culprit is my doPipeSegment function, specifically where 'node' is parented to 'pipe_seg' with: node->setParent(pipe_seg). The full source for this short function is at the end of this message.

Code: Select all

          for (int i = 0; i < num_key_point-1; ++i) {
            tagKeyPoint& p1 = tm.keyPoints[i];
            tagKeyPoint& p2 = tm.keyPoints[i+1];

            core::vector3df v1 = doSetPosition(
              p1.pos.east,      p1.pos.north,       p1.pos.depth,
              TDOffset_Easting, TDOffset_Northing,  TDOffset_Depth);

            core::vector3df v2 = doSetPosition(
              p2.pos.east,      p2.pos.north,       p2.pos.depth,
              TDOffset_Easting, TDOffset_Northing,  TDOffset_Depth);

            irr::scene::ISceneNode* pipe_seg  = m_smgr->addEmptySceneNode();  // Create a parent node for rotation
            irr::scene::IMesh* mesh           = createCylinder(8, 2, pipeRadius);
            irr::scene::IMeshSceneNode* node  = m_smgr->addMeshSceneNode(mesh);
            if( pipe_seg && node ) {
              doPipeSegment(node, pipe_seg, v1, v2);
              // NOTE:  In the above doPipeSegment function, 'node' is parented to 'pipe_seg' with:  node->setParent(pipe_seg)

            // Assign an Irrlicht-compliant ID for each node so that it can be picked and measured
            // Set ID x 100 to allow room for 100 individual IDs associated with each pipe
            // .obj models are set to 100, 200, 300 ...
            // Pipe segments are set to 500, 501, 502 ...

            int node_seg_id = (tm_id * 100) + i;

            node->setID(node_seg_id);  // assign an Irrlicht-compliant ID for each node

            m_pipe_mesh[node_seg_id] = mesh;
            m_pipe_node[node_seg_id] = node;

            // Add bbox + fine selector for each pipe segment mesh + node
            if (addSelectors == true) {

              Selector seg_selector;
              seg_selector.bbox_selector = m_smgr->createTriangleSelectorFromBoundingBox(node);
              seg_selector.fine_selector = m_smgr->createTriangleSelector(mesh, node);
              //
              theSelectorVec.push_back(seg_selector);
            }
            node->setMaterialFlag(video::EMF_LIGHTING, true);  // turn on real lighting
            node->setMaterialTexture(0, tt);
            m_mv_pipe_segments[tm_id].push_back(pipe_seg);
          }
        }
Does that help at all to clarify my problem?

Thanks again,

-Kevin

p.s.--this is the doPipeSegment function, where 'node' is parented.

Code: Select all

bool
wxIrrlichtWindow::doPipeSegment(
  irr::scene::ISceneNode* node,
  irr::scene::ISceneNode* parent,
  irr::core::vector3df& pipePos,
  irr::core::vector3df& pipePos2)
{
  // Compute Euclidean distance from Point A to Point B
  float dx = pipePos.X-pipePos2.X;
  float dy = pipePos.Y-pipePos2.Y;
  float dz = pipePos.Z-pipePos2.Z;
  float pipeScale = sqrt(dx*dx + dy*dy + dz*dz);
  //printf("Euclidean distance between points:  %f\n", pipeScale);

  // Offset points A & B so that A rests at origin
  irr::core::vector3df xformPipePos, xformPipePos2;
  xformPipePos2.X = pipePos2.X - pipePos.X; 
  xformPipePos2.Y = pipePos2.Y - pipePos.Y;
  xformPipePos2.Z = pipePos2.Z - pipePos.Z;
  xformPipePos.X = 0;  xformPipePos.Y = 0;  xformPipePos.Z = 0;

  // Set pipe vector (Point B to origin)
  irr::core::vector3df pipeAxis, pipeAxis_Normalized;
  pipeAxis = xformPipePos2;
  pipeAxis_Normalized = pipeAxis.normalize();  // Normalize to a unit vector:  <x / length, y / length, z / length> with length:  sqrt(dx*dx + dy*dy + dz*dz)

  // Scale the primitive to size, pre-position at the origin for scaling
  node->setScale(irr::core::vector3df(1,pipeScale/2,1));  // scale the primitive to create a pipe segment
  node->setPosition(irr::core::vector3df(0,pipeScale/2,0));  // pre-position the pipe segment at the origin
  node->setParent(parent);

  // Compute angle from the vector <0, 1, 0>, vectorB (a line through two points--the pipe segment)
  irr::core::vector3df startAxis;
  startAxis.X = 0;  startAxis.Y = 1;  startAxis.Z = 0;  // We always start with a Y-up primitive

  // Angle is given by ACOS of the dot product of the two normalized vectors (startAxis, pipeAxis)
  float myAngle;
  // myAngle = 26.5;  // Testing value
  // myAngle = myAngle*(3.14159265/180.0f);  // Convert to radians
  myAngle = acos(startAxis.dotProduct(pipeAxis_Normalized));
  //*
  // printf("Angle (in radians):  %f\n",myAngle);
  // printf("PipeAxisX:  %f\n",pipeAxis_Normalized.X);
  // printf("PipeAxisY:  %f\n",pipeAxis_Normalized.Y);
  // printf("PipeAxisZ:  %f\n",pipeAxis_Normalized.Z);

  // Axis is given by the cross product of the two (normalized?) vectors
  irr::core::vector3df myAxis, MyAxis_Normalized;  // Local axis for pipe segment - must be unit vector
  // myAxis.X = 1;  myAxis.Y = 0;  myAxis.Z = 0;  // Testing value
  myAxis = startAxis.crossProduct(pipeAxis_Normalized);
  MyAxis_Normalized = myAxis.normalize();  // Normalize to a unit vector:  <x / length, y / length, z / length> with length:  sqrt(dx*dx + dy*dy + dz*dz)

  //Use quaternion to compute rotation angles from axis
  irr::core::vector3df myrot;  // Euler angle rotation
  irr::core::quaternion q;  // Quaternion
  q.fromAngleAxis(myAngle, MyAxis_Normalized);
  q.toEuler(myrot);

  // myrot is in radians:  convert to degrees
  myrot.X = myrot.X*(180/3.14159265); myrot.Y = myrot.Y*(180/3.14159265); myrot.Z = myrot.Z*(180/3.14159265);
  // printf("ROT x:  %f\n",myrot.X); printf("ROT y:  %f\n",myrot.Y); printf("ROT z:  %f\n",myrot.Z);
  //*
  parent->setRotation(myrot);

  // Translate into place
  parent->setPosition(pipePos);
  return true;
}
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Yes, that's really strange... ;)
Maybe it's caused by the scaling ???
You could try irr::scene::IMeshManipulator::recalculateBoundingBox(scene::IMeshBuffer * buffer) (but I'm not really sure how to use it, never did it)...

I first would try core::aabbox3d<f32>& irr::scene::ISceneNode::getBoundingBox() and test the extends of the aabbox...
So you can see if the BB is in size it should be, or not (this way I descovered the error I mentioned above)...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Post Reply