raycasting, intersectsWithLine broken in 0.14?

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
dracflamloc
Posts: 142
Joined: Sat Dec 11, 2004 8:13 am
Contact:

raycasting, intersectsWithLine broken in 0.14?

Post by dracflamloc »

[edit] I think it could also possible be something to do with the boundingbox? I have no idea what would make this happen. [/edit]

[edit] If i take out the check for buildings from the weapon firing code, it seems to work just fine. So something is messed up with that building stuff [/edit]

I don't know why, but in 0.12, my zombies would work just fine. They would
cast two rays one angled outt o the left an done angled out to the right. If anything intersected with one of those (buildings), they'd turn the other way. But now they are all just turning all the time! Right in the middle of huge open areas with no problems!

Something is seriously screwy. Also my raycasting from my camera to detect if a zombie is hit by a bullet is very wacky. Every now and then it will work and the zombie will die, but most often it just does absolutely nothing.

It all worked perfectly when compiled with 0.12.

Also please do not suggest using collision animators, etc. I have over 300 zombie entities. Irrlicht chokes if I do built-in collision testing on all those.

Heres a code snippet of my AI collision testing:

Code: Select all

bool AICanMove(int i)
    {
        float lookAhead=0.0f;
        matrix4 mat=entityArray[i].node->getAbsoluteTransformation();
        vector3df dirVec = vector3df(mat.M[8],mat.M[9],mat.M[10]);
        vector3df movVecLeft;
        vector3df movVecRight;
        vector3df nodePos = entityArray[i].node->getPosition();
        line3d<f32> rayRight;
        line3d<f32> rayLeft;

        //get max lookahead distance in case of low fps
        if (aiColLookAhead < 0)
            lookAhead = min(-1*ai::GetTimedAmount(currentTimeMs-lastTimeMs, entityArray[i].movSpeed), aiColLookAhead);
        else
            lookAhead = max(ai::GetTimedAmount(currentTimeMs-lastTimeMs, entityArray[i].movSpeed), aiColLookAhead);

        //right lookahead ray
        movVecRight = dirVec;
        movVecRight.normalize();
        movVecRight.rotateXZBy(aiColLookAngle, vector3df(0,0,0));
        movVecRight *= lookAhead;
        movVecRight += nodePos;
        rayRight = line3d<f32>(nodePos,movVecRight);

        //left lookahead ray
        movVecLeft = dirVec;
        movVecLeft.normalize();
        movVecLeft.rotateXZBy(-1*aiColLookAngle, vector3df(0,0,0));
        movVecLeft *= lookAhead;
        movVecLeft += nodePos;
        rayLeft = line3d<f32>(nodePos,movVecLeft);

        //CHECK FOR BUILDINGS IN THE WAY
        for (int j=0; j<levelSize; j++)
            if (buildingArray[j])
            {
                //if (ai::GetDistance(buildingArray[j],entityArray[i].node) < maxSize)
                //{
                    //if this one hits rotate right
                    if (buildingArray[j]->getTransformedBoundingBox().intersectsWithLine( rayRight ))
                    {
                        entityArray[i].node->setRotation(vector3df(0, entityArray[i].node->getRotation().Y + ai::GetTimedAmount(currentTimeMs-lastTimeMs, entityArray[i].rotSpeed*2), 0));
                        return false;
                    }
                    else
                    {
                        //if this hits go left
                        if (buildingArray[j]->getTransformedBoundingBox().intersectsWithLine( rayLeft ))
                        {
                            entityArray[i].node->setRotation(vector3df(0, entityArray[i].node->getRotation().Y - ai::GetTimedAmount(currentTimeMs-lastTimeMs, entityArray[i].rotSpeed*2), 0));
                            return false;
                        }
                    }
                //}
            }
And here is the bullet raytracing:

Code: Select all

weaponLight->setVisible(true);
                        w_current->setFrameLoop(0,_ANIMATION_LENGTH-1);
                        w_current->setAnimationSpeed(_GUN_FPS);
                        w_current->setLoopMode(false);
                        w_current->setAnimationEndCallback(new anim_cb::CWeaponEnd());

                        line3d<f32> ray = scene->getSceneCollisionManager()->getRayFromScreenCoordinates(position2d<s32>(driver->getScreenSize().Width/2, driver->getScreenSize().Height/2), camera);
                        int eid = -1;
                        float shortestDist = -1.0f;
                        float curDist = 0.0f;

                        //find closest zombie
                        for (int i=0; i<humanCount+zombieCount; i++)
                        {
                            if (entityArray[i].node->getTransformedBoundingBox().intersectsWithLine(ray)) {
                                curDist = ai::GetDistance(camera, entityArray[i].node);
                                if (curDist <= camera->getFarValue()*_CAM_VIS_ENTITY_MOD && (curDist < shortestDist || shortestDist == -1.0f)) {
                                    shortestDist = curDist;
                                    eid=i;
                                }
                            }
                        }

                        //make sure theres not a building in the way
                        if (eid > -1)
                            ray.end = entityArray[eid].node->getPosition(); //sets the end of the line to the zombies pos

                            for (int i=0; i<levelSize; i++)
                            {
                                if (buildingArray[i])
                                    if (buildingArray[i]->getTransformedBoundingBox().intersectsWithLine(ray)) {
                                        eid=-1;
                                        break;
                                    }
                            }

                        //check the walls and ground (who knows?)
                        if (eid > -1)

                        //apply damage
                        if (eid > -1)
                        {
                            //cout<<entityArray[eid].node<<" ID:"<<entityArray[eid].node->getID()<<endl;
                            if (!entityArray[eid].isDead)
                            {
                                int dmgAmount=0;

                                if (w_current==w_pistol)
                                    dmgAmount=_PISTOL_DMG;

                                entityArray[eid].health -= dmgAmount;
If you'd like to see a working version and the non-working version (exactly the same code), you may download them here:
0.12 version:
http://www.dracsoft.com/zips/pnmz-test9.zip

0.14 version:
http://www.dracsoft.com/zips/pnmz-test9-014.zip
Warchief
Posts: 204
Joined: Tue Nov 22, 2005 10:58 am

Post by Warchief »

The intersection between line and bbox seems to be bugged, although i saw a paper with the implementation Irrlicht has.

I successfully get it to work with my own implementation. I will probably post the source code if needed. Lets wait to confirm that there are problems with intersectsWithLine. I also had to introduce a little trick because of precision, failing with 10e-8 decimals and isPointInside function.
Guest

Post by Guest »

I woild be glad if you post your code, cos I am having problems with collision too :)
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

I just tested it: Just replace the aabbox.h file from 0.14.0 with the old one from 0.12.0, recompile the engine and everything should be fine again. sorry.
Warchief
Posts: 204
Joined: Tue Nov 22, 2005 10:58 am

Post by Warchief »

Well i was doing a small demo and then realized that Irr0.12 was working; It was Spintz's mod what was not working.


Anyway, what i have done to avoid Irr-Spintz line vs bbox is:

Code: Select all

plane = Build the six planes defined by the bbox 

// Check every plane
FOR_EACH (plane)
    IF plane::getIntersectionWithLimitedLine( line )
        IF bbox::isPointInside( collisionPoint )
            return true;

return false;

Spintz, could you take a look at your code?

this code works with Niko's, but not with Spintz's:

Code: Select all

		// Build rect
		position2d<s32> mousePos = CURSOR_PTR->getPosition();
		line3d<f32> colLine = COLMAN_PTR->getRayFromScreenCoordinates(mousePos);		

		// Cast collision against BBox1
		if (bbox1.intersectsWithLine( colLine) )
			DRIVER_PTR->draw3DBox(bbox1, COLOR_GREEN);
		else
			DRIVER_PTR->draw3DBox(bbox1, COLOR_RED);

Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

I just finished merging IrrSpintz with 0.14 and all of a sudden I had the same problem.

I wasn't having it before with IrrSpintz-0.12

So change it back to original and I will look at why it doesn't work
Image
Warchief
Posts: 204
Joined: Tue Nov 22, 2005 10:58 am

Post by Warchief »

Well, im having the same problem with Irr-Spintz 0.12 (could be the 'e' and 't' fixes?). Also the terrain not rendered could be around this behaviour [ http://irrlicht.sourceforge.net/phpBB2/ ... php?t=9908 ].
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

terrain rendering has nothing to do with this.
Image
Warchief
Posts: 204
Joined: Tue Nov 22, 2005 10:58 am

Post by Warchief »

Ok. Thought it could be about cam projection line and tiles bbox.
Rv
Posts: 10
Joined: Fri Mar 31, 2006 9:38 am

Post by Rv »

Post Reply