1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package com.jme3.math; 33 34 import com.jme3.export.JmeExporter; 35 import com.jme3.export.JmeImporter; 36 import com.jme3.export.Savable; 37 import java.io.IOException; 38 39 /** 40 * <code>Triangle</code> defines an object for containing triangle information. 41 * The triangle is defined by a collection of three {@link Vector3f} 42 * objects. 43 * 44 * @author Mark Powell 45 * @author Joshua Slack 46 */ 47 public class Triangle extends AbstractTriangle implements Savable, java.io.Serializable { 48 49 static final long serialVersionUID = 1; 50 51 private Vector3f pointa = new Vector3f(); 52 private Vector3f pointb = new Vector3f(); 53 private Vector3f pointc = new Vector3f(); 54 private transient Vector3f center; 55 private transient Vector3f normal; 56 private float projection; 57 private int index; 58 Triangle()59 public Triangle() { 60 } 61 62 /** 63 * Constructor instantiates a new <Code>Triangle</code> object with the 64 * supplied vectors as the points. It is recommended that the vertices 65 * be supplied in a counter clockwise winding to support normals for a 66 * right handed coordinate system. 67 * @param p1 the first point of the triangle. 68 * @param p2 the second point of the triangle. 69 * @param p3 the third point of the triangle. 70 */ Triangle(Vector3f p1, Vector3f p2, Vector3f p3)71 public Triangle(Vector3f p1, Vector3f p2, Vector3f p3) { 72 pointa.set(p1); 73 pointb.set(p2); 74 pointc.set(p3); 75 } 76 77 /** 78 * 79 * <code>get</code> retrieves a point on the triangle denoted by the index 80 * supplied. 81 * @param i the index of the point. 82 * @return the point. 83 */ get(int i)84 public Vector3f get(int i) { 85 switch (i) { 86 case 0: 87 return pointa; 88 case 1: 89 return pointb; 90 case 2: 91 return pointc; 92 default: 93 return null; 94 } 95 } 96 get1()97 public Vector3f get1() { 98 return pointa; 99 } 100 get2()101 public Vector3f get2() { 102 return pointb; 103 } 104 get3()105 public Vector3f get3() { 106 return pointc; 107 } 108 109 /** 110 * 111 * <code>set</code> sets one of the triangle's points to that specified as 112 * a parameter. 113 * @param i the index to place the point. 114 * @param point the point to set. 115 */ set(int i, Vector3f point)116 public void set(int i, Vector3f point) { 117 switch (i) { 118 case 0: 119 pointa.set(point); 120 break; 121 case 1: 122 pointb.set(point); 123 break; 124 case 2: 125 pointc.set(point); 126 break; 127 } 128 } 129 130 /** 131 * 132 * <code>set</code> sets one of the triangle's points to that specified as 133 * a parameter. 134 * @param i the index to place the point. 135 */ set(int i, float x, float y, float z)136 public void set(int i, float x, float y, float z) { 137 switch (i) { 138 case 0: 139 pointa.set(x, y, z); 140 break; 141 case 1: 142 pointb.set(x, y, z); 143 break; 144 case 2: 145 pointc.set(x, y, z); 146 break; 147 } 148 } 149 set1(Vector3f v)150 public void set1(Vector3f v) { 151 pointa.set(v); 152 } 153 set2(Vector3f v)154 public void set2(Vector3f v) { 155 pointb.set(v); 156 } 157 set3(Vector3f v)158 public void set3(Vector3f v) { 159 pointc.set(v); 160 } 161 set(Vector3f v1, Vector3f v2, Vector3f v3)162 public void set(Vector3f v1, Vector3f v2, Vector3f v3) { 163 pointa.set(v1); 164 pointb.set(v2); 165 pointc.set(v3); 166 } 167 168 /** 169 * calculateCenter finds the average point of the triangle. 170 * 171 */ calculateCenter()172 public void calculateCenter() { 173 if (center == null) { 174 center = new Vector3f(pointa); 175 } else { 176 center.set(pointa); 177 } 178 center.addLocal(pointb).addLocal(pointc).multLocal(FastMath.ONE_THIRD); 179 } 180 181 /** 182 * calculateNormal generates the normal for this triangle 183 * 184 */ calculateNormal()185 public void calculateNormal() { 186 if (normal == null) { 187 normal = new Vector3f(pointb); 188 } else { 189 normal.set(pointb); 190 } 191 normal.subtractLocal(pointa).crossLocal(pointc.x - pointa.x, pointc.y - pointa.y, pointc.z - pointa.z); 192 normal.normalizeLocal(); 193 } 194 195 /** 196 * obtains the center point of this triangle (average of the three triangles) 197 * @return the center point. 198 */ getCenter()199 public Vector3f getCenter() { 200 if (center == null) { 201 calculateCenter(); 202 } 203 return center; 204 } 205 206 /** 207 * sets the center point of this triangle (average of the three triangles) 208 * @param center the center point. 209 */ setCenter(Vector3f center)210 public void setCenter(Vector3f center) { 211 this.center = center; 212 } 213 214 /** 215 * obtains the unit length normal vector of this triangle, if set or 216 * calculated 217 * 218 * @return the normal vector 219 */ getNormal()220 public Vector3f getNormal() { 221 if (normal == null) { 222 calculateNormal(); 223 } 224 return normal; 225 } 226 227 /** 228 * sets the normal vector of this triangle (to conform, must be unit length) 229 * @param normal the normal vector. 230 */ setNormal(Vector3f normal)231 public void setNormal(Vector3f normal) { 232 this.normal = normal; 233 } 234 235 /** 236 * obtains the projection of the vertices relative to the line origin. 237 * @return the projection of the triangle. 238 */ getProjection()239 public float getProjection() { 240 return this.projection; 241 } 242 243 /** 244 * sets the projection of the vertices relative to the line origin. 245 * @param projection the projection of the triangle. 246 */ setProjection(float projection)247 public void setProjection(float projection) { 248 this.projection = projection; 249 } 250 251 /** 252 * obtains an index that this triangle represents if it is contained in a OBBTree. 253 * @return the index in an OBBtree 254 */ getIndex()255 public int getIndex() { 256 return index; 257 } 258 259 /** 260 * sets an index that this triangle represents if it is contained in a OBBTree. 261 * @param index the index in an OBBtree 262 */ setIndex(int index)263 public void setIndex(int index) { 264 this.index = index; 265 } 266 computeTriangleNormal(Vector3f v1, Vector3f v2, Vector3f v3, Vector3f store)267 public static Vector3f computeTriangleNormal(Vector3f v1, Vector3f v2, Vector3f v3, Vector3f store) { 268 if (store == null) { 269 store = new Vector3f(v2); 270 } else { 271 store.set(v2); 272 } 273 274 store.subtractLocal(v1).crossLocal(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z); 275 return store.normalizeLocal(); 276 } 277 write(JmeExporter e)278 public void write(JmeExporter e) throws IOException { 279 e.getCapsule(this).write(pointa, "pointa", Vector3f.ZERO); 280 e.getCapsule(this).write(pointb, "pointb", Vector3f.ZERO); 281 e.getCapsule(this).write(pointc, "pointc", Vector3f.ZERO); 282 } 283 read(JmeImporter e)284 public void read(JmeImporter e) throws IOException { 285 pointa = (Vector3f) e.getCapsule(this).readSavable("pointa", Vector3f.ZERO.clone()); 286 pointb = (Vector3f) e.getCapsule(this).readSavable("pointb", Vector3f.ZERO.clone()); 287 pointc = (Vector3f) e.getCapsule(this).readSavable("pointc", Vector3f.ZERO.clone()); 288 } 289 290 @Override clone()291 public Triangle clone() { 292 try { 293 Triangle t = (Triangle) super.clone(); 294 t.pointa = pointa.clone(); 295 t.pointb = pointb.clone(); 296 t.pointc = pointc.clone(); 297 return t; 298 } catch (CloneNotSupportedException e) { 299 throw new AssertionError(); 300 } 301 } 302 } 303