View Javadoc

1   /*
2    * Copyright (C) 2013 AMIS research group, Faculty of Mathematics and Physics, Charles University in Prague, Czech Republic
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16   */
17  package cz.cuni.amis.pogamut.ut2004.agent.navigation.navmesh;
18  
19  import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
20  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
21  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointNeighbourLink;
22  import cz.cuni.amis.pogamut.ut2004.server.impl.UT2004Server;
23  import cz.cuni.amis.pogamut.ut2004.utils.LinkFlag;
24  import javax.vecmath.Vector2d;
25  
26  /**
27   *
28   * @author Jakub Tomek
29   * Holds constants used for navmesh. Used staticaly
30   */
31  public class NavMeshConstants {
32      // storage directories
33      public static String pureMeshReadDir = "meshes\\pure"; 
34      public static String processedMeshDir = "meshes\\processed";
35      public static String pureLevelGeometryReadDir = "meshes\\levelGeometry\\pure"; 
36      public static String processedLevelGeometryDir = "meshes\\levelGeometry\\processed";    
37      
38      // polygon BSP tree params
39      public static int stopSplittingNumberOfPolygons = 1;
40      public static int maxNumberOfPolygonsToTry = 10;
41      public static double maxAllowedSplitFactor = 1.0;
42      
43      // level geometry BSP tree params
44      public static int stopSplittingNumberOfTriangles = 20;
45      public static double stopSplittingSizeOfOneBlock = 40.0;
46      public static double maxAllowedCrossFactor = 0.6;
47      
48      // angles in UT2004
49      public static double UTFullAngle = 65536;
50      public static double UTHalfAngle = UTFullAngle/2;
51      public static double UTQuarterAngle = UTHalfAngle/2; 
52      
53      // forces in formations
54      public static double ForceToTarget = 1;
55      public static double StepSize = 75;
56      // force in zero distance
57      public static double obstacleMaxForce = 1.5;
58      // in this distance the force is down to 0
59      public static double obstacleMaxDistance = 100;
60      
61      /**
62       * how far above or bellow a polygon a bot can stand and still be considered to be standing on it
63       */
64      public static double maxDistanceBotPolygon = 125.0;
65      
66      /**
67       * When building a path, add this number to polygon Z coordinate, so that is is not on the floor (or under), but floating a little above
68       */
69      public static double liftPolygonLocation = 40.0;
70      
71      /**
72       * how far from edge of navmesh should agent stay
73       */
74      public static double agentRadius = 20.0;
75      
76      
77      
78      public static Location getColorForOffMeshConnection(OffMeshEdge oe, UT2004Server server) {
79          
80          NavPoint from = server.getWorldView().get(oe.getFrom().getNavPointId(), NavPoint.class);
81          NavPoint to = server.getWorldView().get(oe.getTo().getNavPointId(), NavPoint.class);
82          NavPointNeighbourLink link = from.getOutgoingEdges().get(oe.getLinkId());
83          
84          //lift is blue
85          if(from.isLiftCenter() || to.isLiftCenter()) return new Location(0, 0, 255);
86          // teleporter is violet
87          if(from.isTeleporter() && to.isTeleporter()) return new Location(150, 0, 255);
88          // return new Location(0, 180, 64);
89          int linkFlags = link.getFlags();
90          if ((linkFlags & LinkFlag.DOOR.get()) > 0) {}
91          if ((linkFlags & LinkFlag.FLY.get()) > 0) {return new Location(255, 0, 0);}
92          if ((linkFlags & LinkFlag.FORCED.get()) > 0) {return new Location(255, 170, 255);}      
93          if ((linkFlags & LinkFlag.LADDER.get()) > 0) {return new Location(255, 0, 0);}
94          if ((linkFlags & LinkFlag.PLAYERONLY.get()) > 0) {return new Location(255, 0, 0);}
95          if ((linkFlags & LinkFlag.PROSCRIBED.get()) > 0) {return new Location(255, 0, 0);}
96          if ((linkFlags & LinkFlag.SPECIAL.get()) > 0) {return new Location(255, 0, 255);}
97          if ((linkFlags & LinkFlag.SWIM.get()) > 0) {return new Location(255, 0, 0);}
98          if ((linkFlags & LinkFlag.WALK.get()) > 0) {}
99          // JUMP is light green
100         if ((linkFlags & LinkFlag.JUMP.get()) > 0) {return new Location(100, 255, 255);}
101         // default
102         return new Location(255,255,100);
103     }
104     
105     /**
106      * Transgorms a 2D vector to angle. Handy for handling relative rotations.
107      * Returns a value between 0 and 65536 (full angle);
108      * @param vector
109      * @return 
110      */
111     public static double transform2DVectorToRotation(Vector2d vector) {
112     
113         double yaw;
114         double x = vector.x;
115         double y = vector.y;
116         
117         if(x==0) {
118             if(y>=0) yaw = UTQuarterAngle;
119             else yaw = 3*UTQuarterAngle;
120         }
121         else {
122             if(y==0) {
123                 if(x>=0) yaw = 0;
124                 else yaw = 2*UTQuarterAngle;
125             }
126             else {
127                 // neither x nor y are 0
128                 // turning right 0-180 degrees
129                 if(y>0) {
130                     // 0-90
131                     if(x>0) {
132                         yaw = 0*UTQuarterAngle + Math.atan(y/x)/(2*Math.PI)*UTFullAngle;
133                     }
134                     // 90-180
135                     else {
136                         yaw = 1*UTQuarterAngle + Math.atan(-x/y)/(2*Math.PI)*UTFullAngle;
137                     }
138                 }
139                 // 180-360
140                 else {
141                     // 180-270
142                     if(x<0) {
143                         yaw = 2*UTQuarterAngle + Math.atan(-y/-x)/(2*Math.PI)*UTFullAngle;
144                     }
145                     // 270-360
146                     else {
147                         yaw = 3*UTQuarterAngle + Math.atan(x/-y)/(2*Math.PI)*UTFullAngle;
148                     }    
149                 }
150             }
151         }        
152         return yaw;      
153     }
154 
155     public static Vector2d transformRotationTo2DVector(double yaw) {
156         
157             Vector2d direction = null;
158         
159             // transorm it to 0..UTFullAngle
160             while(yaw < 0) yaw += UTFullAngle;
161             yaw = yaw % UTFullAngle;
162             // transform it to radians
163             double yawRad = yaw / UTFullAngle * 2*Math.PI;
164             
165             // now we will transform the angle back to vector2d
166             if(yaw % UTQuarterAngle == 0) {
167                 if(yaw==0*UTQuarterAngle) direction = new Vector2d(1,0);
168                 if(yaw==1*UTQuarterAngle) direction = new Vector2d(0,1);
169                 if(yaw==2*UTQuarterAngle) direction = new Vector2d(-1,0);
170                 if(yaw==3*UTQuarterAngle) direction = new Vector2d(0,-1);            
171             }
172             else {
173                 if(yaw < 2*UTQuarterAngle) {
174                     if(yaw < 1*UTQuarterAngle) {
175                         direction = new Vector2d(1, Math.tan(yawRad));
176                     }
177                     else {
178                         direction = new Vector2d(-Math.tan(yawRad-Math.PI/2), 1);
179                     }
180                 }
181                 else {
182                     if(yaw < 3*UTQuarterAngle) {
183                         direction = new Vector2d(-1, Math.tan(yawRad-Math.PI));
184                     }
185                     else {
186                         direction = new Vector2d(-Math.tan(yawRad-3*Math.PI/2), -1);
187                     }
188                 }
189             } 
190             // now we have the direction on x,y.
191             // we must add back the z direction
192             direction.normalize(); 
193             return direction;
194     }
195     
196 }