1 /*
2  * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  *   - Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  *
11  *   - Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *   - Neither the name of Oracle nor the names of its
16  *     contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * This source code is provided to illustrate the usage of a given feature
34  * or technique and has been deliberately simplified. Additional steps
35  * required for a production-quality application, such as security checks,
36  * input validation and proper error handling, might not be present in
37  * this sample code.
38  */
39 
40 
41 
42 /** A fairly conventional 3D matrix object that can transform sets of
43 3D points and perform a variety of manipulations on the transform */
44 class Matrix3D {
45 
46     float xx, xy, xz, xo;
47     float yx, yy, yz, yo;
48     float zx, zy, zz, zo;
49     static final double pi = 3.14159265;
50 
51     /** Create a new unit matrix */
Matrix3D()52     Matrix3D() {
53         xx = 1.0f;
54         yy = 1.0f;
55         zz = 1.0f;
56     }
57 
58     /** Scale by f in all dimensions */
scale(float f)59     void scale(float f) {
60         xx *= f;
61         xy *= f;
62         xz *= f;
63         xo *= f;
64         yx *= f;
65         yy *= f;
66         yz *= f;
67         yo *= f;
68         zx *= f;
69         zy *= f;
70         zz *= f;
71         zo *= f;
72     }
73 
74     /** Scale along each axis independently */
scale(float xf, float yf, float zf)75     void scale(float xf, float yf, float zf) {
76         xx *= xf;
77         xy *= xf;
78         xz *= xf;
79         xo *= xf;
80         yx *= yf;
81         yy *= yf;
82         yz *= yf;
83         yo *= yf;
84         zx *= zf;
85         zy *= zf;
86         zz *= zf;
87         zo *= zf;
88     }
89 
90     /** Translate the origin */
translate(float x, float y, float z)91     void translate(float x, float y, float z) {
92         xo += x;
93         yo += y;
94         zo += z;
95     }
96 
97     /** rotate theta degrees about the y axis */
yrot(double theta)98     void yrot(double theta) {
99         theta *= (pi / 180);
100         double ct = Math.cos(theta);
101         double st = Math.sin(theta);
102 
103         float Nxx = (float) (xx * ct + zx * st);
104         float Nxy = (float) (xy * ct + zy * st);
105         float Nxz = (float) (xz * ct + zz * st);
106         float Nxo = (float) (xo * ct + zo * st);
107 
108         float Nzx = (float) (zx * ct - xx * st);
109         float Nzy = (float) (zy * ct - xy * st);
110         float Nzz = (float) (zz * ct - xz * st);
111         float Nzo = (float) (zo * ct - xo * st);
112 
113         xo = Nxo;
114         xx = Nxx;
115         xy = Nxy;
116         xz = Nxz;
117         zo = Nzo;
118         zx = Nzx;
119         zy = Nzy;
120         zz = Nzz;
121     }
122 
123     /** rotate theta degrees about the x axis */
xrot(double theta)124     void xrot(double theta) {
125         theta *= (pi / 180);
126         double ct = Math.cos(theta);
127         double st = Math.sin(theta);
128 
129         float Nyx = (float) (yx * ct + zx * st);
130         float Nyy = (float) (yy * ct + zy * st);
131         float Nyz = (float) (yz * ct + zz * st);
132         float Nyo = (float) (yo * ct + zo * st);
133 
134         float Nzx = (float) (zx * ct - yx * st);
135         float Nzy = (float) (zy * ct - yy * st);
136         float Nzz = (float) (zz * ct - yz * st);
137         float Nzo = (float) (zo * ct - yo * st);
138 
139         yo = Nyo;
140         yx = Nyx;
141         yy = Nyy;
142         yz = Nyz;
143         zo = Nzo;
144         zx = Nzx;
145         zy = Nzy;
146         zz = Nzz;
147     }
148 
149     /** rotate theta degrees about the z axis */
zrot(double theta)150     void zrot(double theta) {
151         theta *= (pi / 180);
152         double ct = Math.cos(theta);
153         double st = Math.sin(theta);
154 
155         float Nyx = (float) (yx * ct + xx * st);
156         float Nyy = (float) (yy * ct + xy * st);
157         float Nyz = (float) (yz * ct + xz * st);
158         float Nyo = (float) (yo * ct + xo * st);
159 
160         float Nxx = (float) (xx * ct - yx * st);
161         float Nxy = (float) (xy * ct - yy * st);
162         float Nxz = (float) (xz * ct - yz * st);
163         float Nxo = (float) (xo * ct - yo * st);
164 
165         yo = Nyo;
166         yx = Nyx;
167         yy = Nyy;
168         yz = Nyz;
169         xo = Nxo;
170         xx = Nxx;
171         xy = Nxy;
172         xz = Nxz;
173     }
174 
175     /** Multiply this matrix by a second: M = M*R */
mult(Matrix3D rhs)176     void mult(Matrix3D rhs) {
177         float lxx = xx * rhs.xx + yx * rhs.xy + zx * rhs.xz;
178         float lxy = xy * rhs.xx + yy * rhs.xy + zy * rhs.xz;
179         float lxz = xz * rhs.xx + yz * rhs.xy + zz * rhs.xz;
180         float lxo = xo * rhs.xx + yo * rhs.xy + zo * rhs.xz + rhs.xo;
181 
182         float lyx = xx * rhs.yx + yx * rhs.yy + zx * rhs.yz;
183         float lyy = xy * rhs.yx + yy * rhs.yy + zy * rhs.yz;
184         float lyz = xz * rhs.yx + yz * rhs.yy + zz * rhs.yz;
185         float lyo = xo * rhs.yx + yo * rhs.yy + zo * rhs.yz + rhs.yo;
186 
187         float lzx = xx * rhs.zx + yx * rhs.zy + zx * rhs.zz;
188         float lzy = xy * rhs.zx + yy * rhs.zy + zy * rhs.zz;
189         float lzz = xz * rhs.zx + yz * rhs.zy + zz * rhs.zz;
190         float lzo = xo * rhs.zx + yo * rhs.zy + zo * rhs.zz + rhs.zo;
191 
192         xx = lxx;
193         xy = lxy;
194         xz = lxz;
195         xo = lxo;
196 
197         yx = lyx;
198         yy = lyy;
199         yz = lyz;
200         yo = lyo;
201 
202         zx = lzx;
203         zy = lzy;
204         zz = lzz;
205         zo = lzo;
206     }
207 
208     /** Reinitialize to the unit matrix */
unit()209     void unit() {
210         xo = 0;
211         xx = 1;
212         xy = 0;
213         xz = 0;
214         yo = 0;
215         yx = 0;
216         yy = 1;
217         yz = 0;
218         zo = 0;
219         zx = 0;
220         zy = 0;
221         zz = 1;
222     }
223 
224     /** Transform nvert points from v into tv.  v contains the input
225     coordinates in floating point.  Three successive entries in
226     the array constitute a point.  tv ends up holding the transformed
227     points as integers; three successive entries per point */
transform(float v[], int tv[], int nvert)228     void transform(float v[], int tv[], int nvert) {
229         float lxx = xx, lxy = xy, lxz = xz, lxo = xo;
230         float lyx = yx, lyy = yy, lyz = yz, lyo = yo;
231         float lzx = zx, lzy = zy, lzz = zz, lzo = zo;
232         for (int i = nvert * 3; (i -= 3) >= 0;) {
233             float x = v[i];
234             float y = v[i + 1];
235             float z = v[i + 2];
236             tv[i] = (int) (x * lxx + y * lxy + z * lxz + lxo);
237             tv[i + 1] = (int) (x * lyx + y * lyy + z * lyz + lyo);
238             tv[i + 2] = (int) (x * lzx + y * lzy + z * lzz + lzo);
239         }
240     }
241 
242     @Override
toString()243     public String toString() {
244         return ("[" + xo + "," + xx + "," + xy + "," + xz + ";"
245                 + yo + "," + yx + "," + yy + "," + yz + ";"
246                 + zo + "," + zx + "," + zy + "," + zz + "]");
247     }
248 }
249