aboutsummaryrefslogtreecommitdiff
path: root/engine/src/core/com/jme3/math/Triangle.java
blob: 6faa53e531976b1ddc83d771b05b642cfef99f92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
/*
 * Copyright (c) 2009-2010 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.jme3.math;

import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.Savable;
import java.io.IOException;

/**
 * <code>Triangle</code> defines an object for containing triangle information.
 * The triangle is defined by a collection of three {@link Vector3f}
 * objects.
 * 
 * @author Mark Powell
 * @author Joshua Slack
 */
public class Triangle extends AbstractTriangle implements Savable, java.io.Serializable {

    static final long serialVersionUID = 1;

    private Vector3f pointa = new Vector3f();
    private Vector3f pointb = new Vector3f();
    private Vector3f pointc = new Vector3f();
    private transient Vector3f center;
    private transient Vector3f normal;
    private float projection;
    private int index;

    public Triangle() {
    }

    /**
     * Constructor instantiates a new <Code>Triangle</code> object with the
     * supplied vectors as the points. It is recommended that the vertices
     * be supplied in a counter clockwise winding to support normals for a
     * right handed coordinate system.
     * @param p1 the first point of the triangle.
     * @param p2 the second point of the triangle.
     * @param p3 the third point of the triangle.
     */
    public Triangle(Vector3f p1, Vector3f p2, Vector3f p3) {
        pointa.set(p1);
        pointb.set(p2);
        pointc.set(p3);
    }

    /**
     *
     * <code>get</code> retrieves a point on the triangle denoted by the index
     * supplied.
     * @param i the index of the point.
     * @return the point.
     */
    public Vector3f get(int i) {
        switch (i) {
            case 0:
                return pointa;
            case 1:
                return pointb;
            case 2:
                return pointc;
            default:
                return null;
        }
    }

    public Vector3f get1() {
        return pointa;
    }

    public Vector3f get2() {
        return pointb;
    }

    public Vector3f get3() {
        return pointc;
    }

    /**
     *
     * <code>set</code> sets one of the triangle's points to that specified as
     * a parameter.
     * @param i the index to place the point.
     * @param point the point to set.
     */
    public void set(int i, Vector3f point) {
        switch (i) {
            case 0:
                pointa.set(point);
                break;
            case 1:
                pointb.set(point);
                break;
            case 2:
                pointc.set(point);
                break;
        }
    }

    /**
     *
     * <code>set</code> sets one of the triangle's points to that specified as
     * a parameter.
     * @param i the index to place the point.
     */
    public void set(int i, float x, float y, float z) {
        switch (i) {
            case 0:
                pointa.set(x, y, z);
                break;
            case 1:
                pointb.set(x, y, z);
                break;
            case 2:
                pointc.set(x, y, z);
                break;
        }
    }

    public void set1(Vector3f v) {
        pointa.set(v);
    }

    public void set2(Vector3f v) {
        pointb.set(v);
    }

    public void set3(Vector3f v) {
        pointc.set(v);
    }

    public void set(Vector3f v1, Vector3f v2, Vector3f v3) {
        pointa.set(v1);
        pointb.set(v2);
        pointc.set(v3);
    }

    /**
     * calculateCenter finds the average point of the triangle. 
     *
     */
    public void calculateCenter() {
        if (center == null) {
            center = new Vector3f(pointa);
        } else {
            center.set(pointa);
        }
        center.addLocal(pointb).addLocal(pointc).multLocal(FastMath.ONE_THIRD);
    }

    /**
     * calculateNormal generates the normal for this triangle
     *
     */
    public void calculateNormal() {
        if (normal == null) {
            normal = new Vector3f(pointb);
        } else {
            normal.set(pointb);
        }
        normal.subtractLocal(pointa).crossLocal(pointc.x - pointa.x, pointc.y - pointa.y, pointc.z - pointa.z);
        normal.normalizeLocal();
    }

    /**
     * obtains the center point of this triangle (average of the three triangles)
     * @return the center point.
     */
    public Vector3f getCenter() {
        if (center == null) {
            calculateCenter();
        }
        return center;
    }

    /**
     * sets the center point of this triangle (average of the three triangles)
     * @param center the center point.
     */
    public void setCenter(Vector3f center) {
        this.center = center;
    }

    /**
     * obtains the unit length normal vector of this triangle, if set or
     * calculated
     * 
     * @return the normal vector
     */
    public Vector3f getNormal() {
        if (normal == null) {
            calculateNormal();
        }
        return normal;
    }

    /**
     * sets the normal vector of this triangle (to conform, must be unit length)
     * @param normal the normal vector.
     */
    public void setNormal(Vector3f normal) {
        this.normal = normal;
    }

    /**
     * obtains the projection of the vertices relative to the line origin.
     * @return the projection of the triangle.
     */
    public float getProjection() {
        return this.projection;
    }

    /**
     * sets the projection of the vertices relative to the line origin.
     * @param projection the projection of the triangle.
     */
    public void setProjection(float projection) {
        this.projection = projection;
    }

    /**
     * obtains an index that this triangle represents if it is contained in a OBBTree.
     * @return the index in an OBBtree
     */
    public int getIndex() {
        return index;
    }

    /**
     * sets an index that this triangle represents if it is contained in a OBBTree.
     * @param index the index in an OBBtree
     */
    public void setIndex(int index) {
        this.index = index;
    }

    public static Vector3f computeTriangleNormal(Vector3f v1, Vector3f v2, Vector3f v3, Vector3f store) {
        if (store == null) {
            store = new Vector3f(v2);
        } else {
            store.set(v2);
        }

        store.subtractLocal(v1).crossLocal(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z);
        return store.normalizeLocal();
    }

    public void write(JmeExporter e) throws IOException {
        e.getCapsule(this).write(pointa, "pointa", Vector3f.ZERO);
        e.getCapsule(this).write(pointb, "pointb", Vector3f.ZERO);
        e.getCapsule(this).write(pointc, "pointc", Vector3f.ZERO);
    }

    public void read(JmeImporter e) throws IOException {
        pointa = (Vector3f) e.getCapsule(this).readSavable("pointa", Vector3f.ZERO.clone());
        pointb = (Vector3f) e.getCapsule(this).readSavable("pointb", Vector3f.ZERO.clone());
        pointc = (Vector3f) e.getCapsule(this).readSavable("pointc", Vector3f.ZERO.clone());
    }

    @Override
    public Triangle clone() {
        try {
            Triangle t = (Triangle) super.clone();
            t.pointa = pointa.clone();
            t.pointb = pointb.clone();
            t.pointc = pointc.clone();
            return t;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}