2

I have two 3D Gates (points) in a 3D world, and I would like to check if the player has passed between the two gates or passed the right gate or left gate.

So I constructed a vector V (distance) between the two points, and constructed a plane out of the that vector but (Vx, Vz).

I can check now the current distance of the player and know if the player intersects with the plane, but how would I know if he passed the right gate or the left one ? enter image description here

andre_lamothe
  • 2,171
  • 2
  • 41
  • 74

4 Answers4

1

If I get it right (not 100% sure from your drawing) then it is like this:

3D gate

  1. do not test single point

    • use actual and last player's position instead
    • compute the intersection point G between axis given by P0,P1
    • and line P2,P3 which is also player movement vector
    • if no intersection then no passing
    • if none or infinite intersections then player moving along gate not passing (this edge case need to be handled)
  2. one intersection

    • this is non edge case of player passing so
    • if |P0-G|<=d then player is pasing through gate point P0
    • if |P1-G|<=d then player is pasing through gate point P1
    • d is some accuracy distance
    • else compute q=|G-P0|/|P1-P0|
    • if 'q<0' then player is passing on left side
    • if 'q>|P1-P0|' then player is passing on right side
    • if (q>=0) && (q<=|P1-P0|) then player is passing in the middle

some C++ code:

    double x0=?,x1=?,y0=?,y1=?; // input points (axis)
    double x2=?,x3=?,y2=?,y3=?; // input points (line)

    double xx0,yy0,xx1,yy1;
    double kx0,ky0,dx0,dy0,t0;
    double kx1,ky1,dx1,dy1,t1;
    kx0=x0; ky0=y0; dx0=x1-x0; dy0=y1-y0;
    kx1=x2; ky1=y2; dx1=x3-x2; dy1=y3-y2;
    t1=divide(dx0*(ky0-ky1)+dy0*(kx1-kx0),(dx0*dy1)-(dx1*dy0));
    xx1=kx1+(dx1*t1);
    yy1=ky1+(dy1*t1);
    if (fabs(dx0)>=fabs(dy0)) t0=divide(kx1-kx0+(dx1*t1),dx0);
    else                        t0=divide(ky1-ky0+(dy1*t1),dy0);
    xx0=kx0+(dx0*t0);
    yy0=ky0+(dy0*t0);
    // check if intersection exists
    if (fabs(xx1-xx0)<=1e-6) // intersection in both lines are the same
     if (fabs(yy1-yy0)<=1e-6)               
      if ((t1<0.0)||(t1>1.0)) // t1 is in <0,1> ... line bounds
       {
       if (t0<0.0) return "left pass";
       if (t0>1.0) return "right pass";
       return "middle pass";
       }
    return "no pass";

divide:

double divide(double x,double y) { if ((y>=-1e-30)&&(y<=+1e-30)) return 0.0; return x/y; }

[notes]

  • you do not need normal (I first thought that it would be necessary but it isn't)
  • intersection code is extracted from Finding holes in 2d point sets
  • so if I forget to copy something there you can find it
  • if your player does not go through the axis (instead goes below or above it)
  • then you have to modify the intersections and/or project the players points to P0,P1,normal plane before computations
Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • Nice!, that's exactly what I needed. – andre_lamothe Sep 15 '14 at 10:39
  • can I get your contacts? I'm a typical clone of your interests. EE and 3D :) – andre_lamothe Sep 15 '14 at 10:41
  • @AhmedSaleh go here http://stackoverflow.com/a/21658139/2521214 and look for second commend there is an link to mine soundcard mini apps (and also the password to rar) inside in readme you can find the mail address (sorry for so indirect way but post mail address directly in google seen site is SPAM suicide) if you do not understand that site read one of the last comments here http://stackoverflow.com/a/19659648/2521214 – Spektre Sep 15 '14 at 11:28
0

Add two more planes. One to the right and one to the left. Check if the player passes through the plane.

Yay295
  • 1,628
  • 3
  • 17
  • 29
  • I know about that, but that means the artist should add more planes in each level, kinda like AABX.. but I need to do it mathematically. – andre_lamothe Sep 14 '14 at 23:05
0

You could extend the plane so that the player will collide with it whichever side of the gates they go. Then check the X position of the player and compare it with the X position of the gates when the player collides with the plane.

Adam H
  • 1,523
  • 11
  • 21
0

I would put two trigger box colliders at both gates. Then I would keep track of which gate was passed through with a simple class that keeps track of this information.

public class Gate
{
   void OnTriggerEnter(Collider other) 
   {
      GateKeeper.setPassedGateCount(this);
   }
}

Then this GateKeeper class.

public static class GateKeeper
{
    private int count = 0;

    public static void setPassedGateCount(GateKeeper instance)
    {
        count++;
    }
}

The reason I pass the instance of the Gate is so that if you want to, you can check by name, for example, which gate was passed.

apxcode
  • 7,696
  • 7
  • 30
  • 41
  • Yea but I wanted to check if the player passed between the two gates, or passed behind right or left gates. I don't really want the artist to put many boxes for all the gates in 18 levels. – andre_lamothe Sep 15 '14 at 11:14
  • You can add the boxes programmatically yourself. If you don't want to do that, and it seems you are already detecting when a player intersects with a gate, then you can just use the `instance` like on my code to check which gate it was. – apxcode Sep 15 '14 at 19:15