J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 1995-2006 Sun Microsystems, Inc. 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 Sun Microsystems 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 | */ |
| 34 | |
| 35 | /** A fairly conventional 3D matrix object that can transform sets of |
| 36 | 3D points and perform a variety of manipulations on the transform */ |
| 37 | class Matrix3D { |
| 38 | float xx, xy, xz, xo; |
| 39 | float yx, yy, yz, yo; |
| 40 | float zx, zy, zz, zo; |
| 41 | static final double pi = 3.14159265; |
| 42 | /** Create a new unit matrix */ |
| 43 | Matrix3D () { |
| 44 | xx = 1.0f; |
| 45 | yy = 1.0f; |
| 46 | zz = 1.0f; |
| 47 | } |
| 48 | /** Scale by f in all dimensions */ |
| 49 | void scale(float f) { |
| 50 | xx *= f; |
| 51 | xy *= f; |
| 52 | xz *= f; |
| 53 | xo *= f; |
| 54 | yx *= f; |
| 55 | yy *= f; |
| 56 | yz *= f; |
| 57 | yo *= f; |
| 58 | zx *= f; |
| 59 | zy *= f; |
| 60 | zz *= f; |
| 61 | zo *= f; |
| 62 | } |
| 63 | /** Scale along each axis independently */ |
| 64 | void scale(float xf, float yf, float zf) { |
| 65 | xx *= xf; |
| 66 | xy *= xf; |
| 67 | xz *= xf; |
| 68 | xo *= xf; |
| 69 | yx *= yf; |
| 70 | yy *= yf; |
| 71 | yz *= yf; |
| 72 | yo *= yf; |
| 73 | zx *= zf; |
| 74 | zy *= zf; |
| 75 | zz *= zf; |
| 76 | zo *= zf; |
| 77 | } |
| 78 | /** Translate the origin */ |
| 79 | void translate(float x, float y, float z) { |
| 80 | xo += x; |
| 81 | yo += y; |
| 82 | zo += z; |
| 83 | } |
| 84 | /** rotate theta degrees about the y axis */ |
| 85 | void yrot(double theta) { |
| 86 | theta *= (pi / 180); |
| 87 | double ct = Math.cos(theta); |
| 88 | double st = Math.sin(theta); |
| 89 | |
| 90 | float Nxx = (float) (xx * ct + zx * st); |
| 91 | float Nxy = (float) (xy * ct + zy * st); |
| 92 | float Nxz = (float) (xz * ct + zz * st); |
| 93 | float Nxo = (float) (xo * ct + zo * st); |
| 94 | |
| 95 | float Nzx = (float) (zx * ct - xx * st); |
| 96 | float Nzy = (float) (zy * ct - xy * st); |
| 97 | float Nzz = (float) (zz * ct - xz * st); |
| 98 | float Nzo = (float) (zo * ct - xo * st); |
| 99 | |
| 100 | xo = Nxo; |
| 101 | xx = Nxx; |
| 102 | xy = Nxy; |
| 103 | xz = Nxz; |
| 104 | zo = Nzo; |
| 105 | zx = Nzx; |
| 106 | zy = Nzy; |
| 107 | zz = Nzz; |
| 108 | } |
| 109 | /** rotate theta degrees about the x axis */ |
| 110 | void xrot(double theta) { |
| 111 | theta *= (pi / 180); |
| 112 | double ct = Math.cos(theta); |
| 113 | double st = Math.sin(theta); |
| 114 | |
| 115 | float Nyx = (float) (yx * ct + zx * st); |
| 116 | float Nyy = (float) (yy * ct + zy * st); |
| 117 | float Nyz = (float) (yz * ct + zz * st); |
| 118 | float Nyo = (float) (yo * ct + zo * st); |
| 119 | |
| 120 | float Nzx = (float) (zx * ct - yx * st); |
| 121 | float Nzy = (float) (zy * ct - yy * st); |
| 122 | float Nzz = (float) (zz * ct - yz * st); |
| 123 | float Nzo = (float) (zo * ct - yo * st); |
| 124 | |
| 125 | yo = Nyo; |
| 126 | yx = Nyx; |
| 127 | yy = Nyy; |
| 128 | yz = Nyz; |
| 129 | zo = Nzo; |
| 130 | zx = Nzx; |
| 131 | zy = Nzy; |
| 132 | zz = Nzz; |
| 133 | } |
| 134 | /** rotate theta degrees about the z axis */ |
| 135 | void zrot(double theta) { |
| 136 | theta *= (pi / 180); |
| 137 | double ct = Math.cos(theta); |
| 138 | double st = Math.sin(theta); |
| 139 | |
| 140 | float Nyx = (float) (yx * ct + xx * st); |
| 141 | float Nyy = (float) (yy * ct + xy * st); |
| 142 | float Nyz = (float) (yz * ct + xz * st); |
| 143 | float Nyo = (float) (yo * ct + xo * st); |
| 144 | |
| 145 | float Nxx = (float) (xx * ct - yx * st); |
| 146 | float Nxy = (float) (xy * ct - yy * st); |
| 147 | float Nxz = (float) (xz * ct - yz * st); |
| 148 | float Nxo = (float) (xo * ct - yo * st); |
| 149 | |
| 150 | yo = Nyo; |
| 151 | yx = Nyx; |
| 152 | yy = Nyy; |
| 153 | yz = Nyz; |
| 154 | xo = Nxo; |
| 155 | xx = Nxx; |
| 156 | xy = Nxy; |
| 157 | xz = Nxz; |
| 158 | } |
| 159 | /** Multiply this matrix by a second: M = M*R */ |
| 160 | void mult(Matrix3D rhs) { |
| 161 | float lxx = xx * rhs.xx + yx * rhs.xy + zx * rhs.xz; |
| 162 | float lxy = xy * rhs.xx + yy * rhs.xy + zy * rhs.xz; |
| 163 | float lxz = xz * rhs.xx + yz * rhs.xy + zz * rhs.xz; |
| 164 | float lxo = xo * rhs.xx + yo * rhs.xy + zo * rhs.xz + rhs.xo; |
| 165 | |
| 166 | float lyx = xx * rhs.yx + yx * rhs.yy + zx * rhs.yz; |
| 167 | float lyy = xy * rhs.yx + yy * rhs.yy + zy * rhs.yz; |
| 168 | float lyz = xz * rhs.yx + yz * rhs.yy + zz * rhs.yz; |
| 169 | float lyo = xo * rhs.yx + yo * rhs.yy + zo * rhs.yz + rhs.yo; |
| 170 | |
| 171 | float lzx = xx * rhs.zx + yx * rhs.zy + zx * rhs.zz; |
| 172 | float lzy = xy * rhs.zx + yy * rhs.zy + zy * rhs.zz; |
| 173 | float lzz = xz * rhs.zx + yz * rhs.zy + zz * rhs.zz; |
| 174 | float lzo = xo * rhs.zx + yo * rhs.zy + zo * rhs.zz + rhs.zo; |
| 175 | |
| 176 | xx = lxx; |
| 177 | xy = lxy; |
| 178 | xz = lxz; |
| 179 | xo = lxo; |
| 180 | |
| 181 | yx = lyx; |
| 182 | yy = lyy; |
| 183 | yz = lyz; |
| 184 | yo = lyo; |
| 185 | |
| 186 | zx = lzx; |
| 187 | zy = lzy; |
| 188 | zz = lzz; |
| 189 | zo = lzo; |
| 190 | } |
| 191 | |
| 192 | /** Reinitialize to the unit matrix */ |
| 193 | void unit() { |
| 194 | xo = 0; |
| 195 | xx = 1; |
| 196 | xy = 0; |
| 197 | xz = 0; |
| 198 | yo = 0; |
| 199 | yx = 0; |
| 200 | yy = 1; |
| 201 | yz = 0; |
| 202 | zo = 0; |
| 203 | zx = 0; |
| 204 | zy = 0; |
| 205 | zz = 1; |
| 206 | } |
| 207 | /** Transform nvert points from v into tv. v contains the input |
| 208 | coordinates in floating point. Three successive entries in |
| 209 | the array constitute a point. tv ends up holding the transformed |
| 210 | points as integers; three successive entries per point */ |
| 211 | void transform(float v[], int tv[], int nvert) { |
| 212 | float lxx = xx, lxy = xy, lxz = xz, lxo = xo; |
| 213 | float lyx = yx, lyy = yy, lyz = yz, lyo = yo; |
| 214 | float lzx = zx, lzy = zy, lzz = zz, lzo = zo; |
| 215 | for (int i = nvert * 3; (i -= 3) >= 0;) { |
| 216 | float x = v[i]; |
| 217 | float y = v[i + 1]; |
| 218 | float z = v[i + 2]; |
| 219 | tv[i ] = (int) (x * lxx + y * lxy + z * lxz + lxo); |
| 220 | tv[i + 1] = (int) (x * lyx + y * lyy + z * lyz + lyo); |
| 221 | tv[i + 2] = (int) (x * lzx + y * lzy + z * lzz + lzo); |
| 222 | } |
| 223 | } |
| 224 | public String toString() { |
| 225 | return ("[" + xo + "," + xx + "," + xy + "," + xz + ";" |
| 226 | + yo + "," + yx + "," + yy + "," + yz + ";" |
| 227 | + zo + "," + zx + "," + zy + "," + zz + "]"); |
| 228 | } |
| 229 | } |