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 433D points and perform a variety of manipulations on the transform */ 44class 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 */ 52 Matrix3D() { 53 xx = 1.0f; 54 yy = 1.0f; 55 zz = 1.0f; 56 } 57 58 /** Scale by f in all dimensions */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 243 public String toString() { 244 return ("[" + xo + "," + xx + "," + xy + "," + xz + ";" 245 + yo + "," + yx + "," + yy + "," + yz + ";" 246 + zo + "," + zx + "," + zy + "," + zz + "]"); 247 } 248} 249