classifyPointRelation (and probably getDistanceTo) bug

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
Anderson
Posts: 5
Joined: Wed Mar 28, 2012 9:30 pm

classifyPointRelation (and probably getDistanceTo) bug

Post by Anderson »

Background: I was trying to create Valve Hammer Editor (used for creating Half-Life-like games maps) .MAP file reader. In this map file, all the blocks (let's speak about paralelepipeds only) are specified by 6 plains by which this block is cut. Every plain has 3 vertexes. These plains' vertexes are always lying on 3 out of 4 edge's vertexes, so I went the easiest way - to detect the fourth vertex for every face and then draw 2 triangles for it. I decided to use classifyPointRelation for this (although using getInteractionWithPlanes for vertex calculation still seems to be much better and most correct solution for me, but anyway).

Problem: So, let's say I have a plane3di myPlane that is defined by 3 vertexes:

Vertex 1: -96 -128 -32
Vertex 2: -96 -128 32
Vertex 3: 256 -128 32

Next, let's say I got some vertex that DOES NOT belong to this plain (is not planar): -96, -384, 32

For some reason, myPlane.classifyPointRelation(vertex3di(-96, -384, 32)) returns ISREL3D_PLANAR. And that was for some other values, however 95% of all blocks (I had ~30 of them in my world) were drawn correctly.

To speed things up: the Y values for all 3 myPlane-defining vertexes are the same, that means this plane is parallel to XZ plane. Thus, any poing that has diverent Y value authomatically doesn't belong to myPlane. That's it.

My solution was to make a function for myself to calculate if the point belongs to plain specified by other three points. It is based on matrix principle.
Here is it:

Code: Select all

bool isPointOnPlane(vector3di p1, vector3di p2, vector3di p3, vector3di point)
{
        return ((point.X-p1.X)*(p2.Y-p1.Y)*(p3.Z-p1.Z)+
        (point.Y-p1.Y)*(p2.Z-p1.Z)*(p3.X-p1.X)+
        (point.Z-p1.Z)*(p3.Y-p1.Y)*(p2.X-p1.X)-
        (point.Z-p1.Z)*(p2.Y-p1.Y)*(p3.X-p1.X)-
        (point.Y-p1.Y)*(p2.X-p1.X)*(p3.Z-p1.Z)-
        (point.X-p1.X)*(p2.Z-p1.Z)*(p3.Y-p1.Y))?false:true;
}
With this function everything started to display correct. I currently use it.

Looking forward to reply and willing to contribute if I can :)

BTW, I use Irrlicht v1.7.3.

Before:
Image

After:
Image
Last edited by Anderson on Thu Mar 29, 2012 11:15 am, edited 4 times in total.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: classifyPointRelation (and probably getDistanceTo) bug

Post by CuteAlien »

plane3d::classifyPointRelation does not return a boolean but values from an enum (EIntersectionRelation3D). So for example ISREL3D_BACK would be one of the values which would be "true" when you cast them to a boolean.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Anderson
Posts: 5
Joined: Wed Mar 28, 2012 9:30 pm

Re: classifyPointRelation (and probably getDistanceTo) bug

Post by Anderson »

Sorry, i misspelled. I meant it returns ISREL3D_PLANAR. I edited first post.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: classifyPointRelation (and probably getDistanceTo) bug

Post by CuteAlien »

Yeah, it seems plane3d wasn't really written with integers in mind - it's trying to use an integer for variable "Normal" in that case (and there are not many normals that work with integers...). Tricky problem, basically integer types and floating point types should have nearly 2 different classes here (or I get lot's of ugly casts). I run into this problem rather often lately (fixed a few cases for lines already) as I'm also right now working a lot with integers. I guess the core templates where really only meant to be used with floating point numbers.

I'm not sure right now if template instantiation allows using different variables depending on type, have to read up on this. Otherwise I guess I have to use vector3df for Normal and maybe write functions without casts for irr::f32 and cast for the rest. Or I could use vector3d<irr::f64> for Normal and cast always to avoid losing precision when it's used with f64. Hard choice... usually I decide to keep it fast for irr::f32 as that's more or less the default for Irrlicht.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Anderson
Posts: 5
Joined: Wed Mar 28, 2012 9:30 pm

Re: classifyPointRelation (and probably getDistanceTo) bug

Post by Anderson »

CuteAlien, actually, I totally agree with you about f32s. I used integers just because there was same problem with floats in classifyPointRelation, integers seemed to fix that, but not completely.
Post Reply