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
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
package my3d;
import javafx.scene.paint.Color;
public class _math3d {
public static class _point {
public double x, y;
public _point() { x = 0; y = 0; }
public _point(double x, double y) {
this.x = x;
this.y = y;
}
public _point set(double x, double y) {
this.x = x; this.y = y;
return this;
}
}
public static class _vector {
public double x, y, z;
public _vector() { x = 0; y = 0; z = 0; }
public _vector(double x, double y, double z) {
this.x = x; this.y = y; this.z = z;
}
public _vector(_vector v) { x = v.x; y = v.y; z = v.z; }
public _vector set(double x, double y, double z) {
this.x = x; this.y = y; this.z = z;
return this;
}
public _vector set(_vector v) {
x = v.x; y = v.y; z = v.z;
return this;
}
}
public static class _matrix {
_vector x, y, z;
public _matrix() { this(1, 0, 0, 0, 1, 0, 0, 0, 1); }
private _matrix(
double xx, double xy, double xz,
double yx, double yy, double yz,
double zx, double zy, double zz) {
x = new _vector(xx, xy, xz);
y = new _vector(yx, yy, yz);
z = new _vector(zx, zy, zz);
}
private _matrix set(
double xx, double xy, double xz,
double yx, double yy, double yz,
double zx, double zy, double zz) {
x.x = xx; x.y = xy; x.z = xz;
y.x = yx; y.y = yy; y.z = yz;
z.x = zx; z.y = zy; z.z = zz;
return this;
}
public _matrix set(_matrix m) {
x.x = m.x.x; x.y = m.x.y; x.z = m.x.z;
y.x = m.y.x; y.y = m.y.y; y.z = m.y.z;
z.x = m.z.x; z.y = m.z.y; z.z = m.z.z;
return this;
}
public static _matrix rot_x(double t, _matrix mo) {
mo.set(
1, 0, 0,
0, Math.cos(t), Math.sin(t),
0, -Math.sin(t), Math.cos(t));
return mo;
}
public static _matrix rot_y(double t, _matrix mo) {
mo.set(
Math.cos(t), 0, -Math.sin(t),
0, 1, 0,
Math.sin(t), 0, Math.cos(t));
return mo;
}
public static _matrix rot_z(double t, _matrix mo) {
mo.set(
Math.cos(t), Math.sin(t), 0,
-Math.sin(t), Math.cos(t), 0,
0, 0, 1);
return mo;
}
public static _matrix scale(double k, _matrix mo) {
return mo.set(
k, 0, 0,
0, k, 0,
0, 0, k);
}
}
public static class _transform {
public _matrix orientation;
public _vector position;
public _transform() {
this(new _matrix(), new _vector());
}
public _transform(_matrix orientation) {
this(orientation, new _vector());
}
public _transform(_vector position) {
this(new _matrix(), position);
}
public _transform(_matrix orientation, _vector position) {
this.orientation = orientation;
this.position = position;
}
/* public _transform set(_transform tf) {
orientation.set(tf.orientation);
position.set(tf.position);
return this;
}
*/ }
public static _vector mul(_matrix m, _vector v, _vector vo) {
double x = v.x, y = v.y, z = v.z;
vo.x = m.x.x * x + m.y.x * y + m.z.x * z;
vo.y = m.x.y * x + m.y.y * y + m.z.y * z;
vo.z = m.x.z * x + m.y.z * y + m.z.z * z;
return vo;
}
public static _vector mul(_transform tf, _vector v, _vector vo) {
_matrix o = tf.orientation;
_vector p = tf.position;
double x = v.x, y = v.y, z = v.z;
vo.x = o.x.x * x + o.y.x * y + o.z.x * z + p.x;
vo.y = o.x.y * x + o.y.y * y + o.z.y * z + p.y;
vo.z = o.x.z * x + o.y.z * y + o.z.z * z + p.z;
return vo;
}
private static _vector v_buf1 = new _vector(), v_buf2 = new _vector();
public static _matrix mul(_matrix m1, _matrix m2, _matrix mo) {
mul(m1, m2.x, v_buf1);
mul(m1, m2.y, v_buf2);
mul(m1, m2.z, mo.z);
mo.x.set(v_buf1); mo.y.set(v_buf2);
return mo;
}
public static _vector add(_vector v1, _vector v2, _vector vo) {
vo.x = v1.x + v2.x;
vo.y = v1.y + v2.y;
vo.z = v1.z + v2.z;
return vo;
}
// 内積・外積
public static _vector sub(_vector v1, _vector v2, _vector vo) {
vo.x = v1.x - v2.x;
vo.y = v1.y - v2.y;
vo.z = v1.z - v2.z;
return vo;
}
public static double dot(_vector v1, _vector v2) {
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
public static _vector cross(_vector v1, _vector v2, _vector vo) {
double x = v1.y * v2.z - v1.z * v2.y;
double y = v1.z * v2.x - v1.x * v2.z;
vo.z = v1.x * v2.y - v1.y * v2.x;
vo.x = x; vo.y = y;
return vo;
}
// 光源処理
public static _vector mul(_vector v, double k, _vector vo) {
vo.x = v.x * k; vo.y = v.y * k; vo.z = v.z * k;
return vo;
}
public static double len(_vector v) {
return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
public static _vector normalize(_vector v, _vector vo) {
return mul(v, 1 / len(v), vo);
}
public static Color mul(Color c, double k) {
return new Color(
c.getRed() * k,
c.getGreen() * k,
c.getBlue() * k,
1);
}
// クリッピング
public static _vector lerp(_vector v1, _vector v2,
double t1, _vector vo) {
double t2 = 1 - t1;
vo.x = v1.x * t1 + v2.x * t2;
vo.y = v1.y * t1 + v2.y * t2;
vo.z = v1.z * t1 + v2.z * t2;
return vo;
}
// 座標の親子関係
public static _transform mul(_transform tf1, _transform tf2, _transform tfo) {
mul(tf1, tf2.position, tfo.position);
mul(tf1.orientation, tf2.orientation, tfo.orientation);
return tfo;
}
public static _matrix inv(_matrix m, _matrix mo) {
return mo.set(
m.x.x, m.y.x, m.z.x,
m.x.y, m.y.y, m.z.y,
m.x.z, m.y.z, m.z.z);
}
public static _transform inv(_transform tf, _transform tfo) {
inv(tf.orientation, tfo.orientation);
mul(tfo.orientation, mul(tf.position, -1, tfo.position), tfo.position);
return tfo;
}
// クォータニオン
public static class _quaternion {
public double w, x, y, z;
public _quaternion() { this(1, 0, 0, 0); }
private _quaternion(double w, double x, double y, double z) {
this.w = w;
this.x = x;
this.y = y;
this.z = z;
}
private _quaternion set(double w, double x, double y, double z) {
this.w = w;
this.x = x;
this.y = y;
this.z = z;
return this;
}
public _quaternion set(_quaternion q) {
w = q.w; x = q.x; y = q.y; z = q.z;
return this;
}
public static _quaternion rot_v(_vector v, double t, _quaternion qo) {
t /= 2;
normalize(v, v_buf1);
qo.w = Math.cos(t);
qo.x = v_buf1.x * Math.sin(t);
qo.y = v_buf1.y * Math.sin(t);
qo.z = v_buf1.z * Math.sin(t);
return qo;
}
public _matrix to_matrix(_matrix mo) {
double wx, wy, wz, xx, yy, zz, xy, yz, zx;
wx = 2 * w * x;
wy = 2 * w * y;
wz = 2 * w * z;
xx = 2 * x * x;
yy = 2 * y * y;
zz = 2 * z * z;
xy = 2 * x * y;
yz = 2 * y * z;
zx = 2 * z * x;
return mo.set(
1 - yy - zz, xy + wz, zx - wy,
xy - wz, 1 - zz - xx, yz + wx,
zx + wy, yz - wx, 1 - xx - yy);
}
public static _quaternion rot_x(double t, _quaternion qo) {
t /= 2;
return qo.set(Math.cos(t), Math.sin(t), 0, 0);
}
public static _quaternion rot_y(double t, _quaternion qo) {
t /= 2;
return qo.set(Math.cos(t), 0, Math.sin(t), 0);
}
public static _quaternion rot_z(double t, _quaternion qo) {
t /= 2;
return qo.set(Math.cos(t), 0, 0, Math.sin(t));
}
private static _quaternion q_buf1 = new _quaternion(), q_buf2 = new _quaternion();
public static _quaternion euler(double tx, double ty, double tz, _quaternion qo) {
return _math3d.mul(
_quaternion.rot_y(ty, qo),
_math3d.mul(
_quaternion.rot_x(tx, q_buf1),
_quaternion.rot_z(tz, q_buf2), q_buf2),
qo);
}
}
public static _quaternion mul(_quaternion q1, _quaternion q2, _quaternion qo) {
double w, x, y;
w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z;
qo.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x;
qo.w = w; qo.x = x; qo.y = y;
return qo;
}
public static double dot(_quaternion q1, _quaternion q2) {
return q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z;
}
public static _quaternion slerp(_quaternion q1, _quaternion q2, double t, _quaternion qo) {
double w = Math.acos(dot(q1, q2)), sin_w = Math.sin(w);
if (Math.abs(sin_w) < 1.0e-3)
return q1;
double t1 = Math.sin(t * w) / sin_w;
double t2 = Math.sin((1 - t) * w) / sin_w;
qo.w = q1.w * t2 + q2.w * t1;
qo.x = q1.x * t2 + q2.x * t1;
qo.y = q1.y * t2 + q2.y * t1;
qo.z = q1.z * t2 + q2.z * t1;
return qo;
}
// Zバッファ法
public static int to_argb(Color color) {
return 0xff000000 |
((int)(color.getRed() * 255) << 16) |
((int)(color.getGreen() * 255) << 8) |
((int)(color.getBlue() * 255));
}
public static int mul(int c, int k) {
c =
((c & 0xff0000) * k) & 0xff000000 |
((c & 0xff00) * k) & 0xff0000 |
((c & 0xff) * k) & 0xff00;
return 0xff000000 | (c >> 8);
}
// スムーズ・シェーディング
public static int mul_add(int c, int diffuse, int speculer) {
int r, g, b;
r = ((c & 0xff0000) * diffuse >>> 24) + speculer;
g = ((c & 0xff00) * diffuse >>> 16) + speculer;
b = ((c & 0xff) * diffuse >>> 8) + speculer;
return
(0xff000000) |
(Math.min(r, 0xff) << 16) |
(Math.min(g, 0xff) << 8) |
(Math.min(b, 0xff));
}
public static _point lerp(
_point p1, _point p2,
double t1,
_point po) {
double t2 = 1 - t1;
po.x = p1.x * t1 + p2.x * t2;
po.y = p1.y * t1 + p2.y * t2;
return po;
}
public static _point lerp(
_point p1, _point p2, _point p3,
double t1, double t2, double t3,
_point po) {
po.x = p1.x * t1 + p2.x * t2 + p3.x * t3;
po.y = p1.y * t1 + p2.y * t2 + p3.y * t3;
return po;
}
public static _point lerp(
_point p1, _point p2, _point p3, _point p4,
double t1, double t2, double t3,
_point po) {
if (t1 > (1 - 10e-3)) return lerp(p1, p4, 0.5, po);
lerp(p1, p4, t2 / (1 - t1), po);
return lerp(po, p2, p3, t1, t2, t3, po);
}
public static _vector lerp(
_vector v1, _vector v2,
double t1, double t2,
_vector vo) {
vo.x = v1.x * t1 + v2.x * t2;
vo.y = v1.y * t1 + v2.y * t2;
vo.z = v1.z * t1 + v2.z * t2;
return vo;
}
public static _vector lerp(
_vector v1, _vector v2, _vector v3,
double t1, double t2, double t3,
_vector vo) {
vo.x = v1.x * t1 + v2.x * t2 + v3.x * t3;
vo.y = v1.y * t1 + v2.y * t2 + v3.y * t3;
vo.z = v1.z * t1 + v2.z * t2 + v3.z * t3;
return vo;
}
// テクスチャ
public static int add(int c1, int c2) {
int t1 = c2 >>> 24;
if (t1 == 0xff)
return c2;
else if (t1 == 0)
return c1;
int t2 = 0xff - t1;
int c =
((c1 & 0xff0000) * t2 + (c2 & 0xff0000) * t1) & 0xff000000 |
((c1 & 0xff00) * t2 + (c2 & 0xff00) * t1) & 0xff0000 |
((c1 & 0xff) * t2 + (c2 & 0xff) * t1) & 0xff00;
return 0xff000000 | (c >>> 8);
}
}