~holger-seelig/cobweb.js/trunk

« back to all changes in this revision

Viewing changes to src/standard/Math/Geometry/ViewVolume.js

  • Committer: Holger Seelig
  • Date: 2017-08-22 04:53:24 UTC
  • Revision ID: holger.seelig@yahoo.de-20170822045324-4of4xxgt79669gbt
Switched to npm.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: JavaScript; coding: utf-8; tab-width: 3; indent-tabs-mode: tab; c-basic-offset: 3 -*-
 
2
 *******************************************************************************
 
3
 *
 
4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
5
 *
 
6
 * Copyright create3000, Scheffelstraße 31a, Leipzig, Germany 2011.
 
7
 *
 
8
 * All rights reserved. Holger Seelig <holger.seelig@yahoo.de>.
 
9
 *
 
10
 * The copyright notice above does not evidence any actual of intended
 
11
 * publication of such source code, and is an unpublished work by create3000.
 
12
 * This material contains CONFIDENTIAL INFORMATION that is the property of
 
13
 * create3000.
 
14
 *
 
15
 * No permission is granted to copy, distribute, or create derivative works from
 
16
 * the contents of this software, in whole or in part, without the prior written
 
17
 * permission of create3000.
 
18
 *
 
19
 * NON-MILITARY USE ONLY
 
20
 *
 
21
 * All create3000 software are effectively free software with a non-military use
 
22
 * restriction. It is free. Well commented source is provided. You may reuse the
 
23
 * source in any way you please with the exception anything that uses it must be
 
24
 * marked to indicate is contains 'non-military use only' components.
 
25
 *
 
26
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
27
 *
 
28
 * Copyright 2015, 2016 Holger Seelig <holger.seelig@yahoo.de>.
 
29
 *
 
30
 * This file is part of the Cobweb Project.
 
31
 *
 
32
 * Cobweb is free software: you can redistribute it and/or modify it under the
 
33
 * terms of the GNU General Public License version 3 only, as published by the
 
34
 * Free Software Foundation.
 
35
 *
 
36
 * Cobweb is distributed in the hope that it will be useful, but WITHOUT ANY
 
37
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 
38
 * A PARTICULAR PURPOSE. See the GNU General Public License version 3 for more
 
39
 * details (a copy is included in the LICENSE file that accompanied this code).
 
40
 *
 
41
 * You should have received a copy of the GNU General Public License version 3
 
42
 * along with Cobweb.  If not, see <http://www.gnu.org/licenses/gpl.html> for a
 
43
 * copy of the GPLv3 License.
 
44
 *
 
45
 * For Silvio, Joy and Adi.
 
46
 *
 
47
 ******************************************************************************/
 
48
 
 
49
 
 
50
define ([
 
51
        "jquery",
 
52
        "standard/Math/Geometry/Line3",
 
53
        "standard/Math/Geometry/Plane3",
 
54
        "standard/Math/Geometry/Triangle3",
 
55
        "standard/Math/Numbers/Vector3",
 
56
        "standard/Math/Numbers/Vector4",
 
57
        "standard/Math/Numbers/Matrix4",
 
58
],
 
59
function ($, Line3, Plane3, Triangle3, Vector3, Vector4, Matrix4)
 
60
{
 
61
"use strict";
 
62
 
 
63
        var
 
64
                p1     = new Vector3 (0, 0, 0),
 
65
                p2     = new Vector3 (0, 0, 0),
 
66
                p3     = new Vector3 (0, 0, 0),
 
67
                p4     = new Vector3 (0, 0, 0),
 
68
                p5     = new Vector3 (0, 0, 0),
 
69
                p6     = new Vector3 (0, 0, 0),
 
70
                near   = new Vector3 (0, 0, 0),
 
71
                far    = new Vector3 (0, 0, 0),
 
72
                matrix = new Matrix4 (),
 
73
                normal = new Vector3 (0, 0, 0),
 
74
                vin    = new Vector4 (0, 0, 0, 0);
 
75
 
 
76
        function ViewVolume ()
 
77
        {
 
78
                this .viewport = new Vector4 (0, 0, 0, 0);
 
79
                this .scissor  = new Vector4 (0, 0, 0, 0);
 
80
                
 
81
                this .planes = [
 
82
                        new Plane3 (Vector3 .Zero, Vector3 .Zero),  // front
 
83
                        new Plane3 (Vector3 .Zero, Vector3 .Zero),  // left
 
84
                        new Plane3 (Vector3 .Zero, Vector3 .Zero),  // right
 
85
                        new Plane3 (Vector3 .Zero, Vector3 .Zero),  // top
 
86
                        new Plane3 (Vector3 .Zero, Vector3 .Zero),  // bottom
 
87
                        new Plane3 (Vector3 .Zero, Vector3 .Zero),  // back
 
88
                ];
 
89
        }
 
90
 
 
91
        ViewVolume .prototype =
 
92
        {
 
93
                constructor: ViewVolume,
 
94
                set: function (projectionMatrix, viewport, scissor)
 
95
                {
 
96
                        try
 
97
                        {
 
98
                                this .viewport .assign (viewport);
 
99
                                this .scissor  .assign (scissor);
 
100
 
 
101
                                var
 
102
                                        x1 = scissor [0],
 
103
                                        x2 = scissor [0] + scissor [2],
 
104
                                        y1 = scissor [1],
 
105
                                        y2 = scissor [1] + scissor [3];
 
106
 
 
107
                                matrix .assign (projectionMatrix) .inverse ();
 
108
 
 
109
                                ViewVolume .unProjectPointMatrix (x1, y2, 1, matrix, viewport, p1),
 
110
                                ViewVolume .unProjectPointMatrix (x1, y1, 1, matrix, viewport, p2),
 
111
                                ViewVolume .unProjectPointMatrix (x1, y1, 0, matrix, viewport, p3),
 
112
                                ViewVolume .unProjectPointMatrix (x2, y1, 0, matrix, viewport, p4),
 
113
                                ViewVolume .unProjectPointMatrix (x2, y2, 0, matrix, viewport, p5),
 
114
                                ViewVolume .unProjectPointMatrix (x2, y2, 1, matrix, viewport, p6);
 
115
 
 
116
                                this .planes [0] .set (p4, Triangle3 .normal (p3, p4, p5, normal));  // front
 
117
                                this .planes [1] .set (p2, Triangle3 .normal (p1, p2, p3, normal));  // left
 
118
                                this .planes [2] .set (p5, Triangle3 .normal (p6, p5, p4, normal));  // right
 
119
                                this .planes [3] .set (p6, Triangle3 .normal (p5, p6, p1, normal));  // top
 
120
                                this .planes [4] .set (p3, Triangle3 .normal (p4, p3, p2, normal));  // bottom
 
121
                                this .planes [5] .set (p1, Triangle3 .normal (p2, p1, p6, normal));  // back  
 
122
 
 
123
                                this .valid = true;
 
124
                        }
 
125
                        catch (error)
 
126
                        {
 
127
                                this .valid = false;
 
128
                                console .log (error);
 
129
                        }
 
130
 
 
131
                        return this;
 
132
                },
 
133
                getViewport: function ()
 
134
                {
 
135
                        return this .viewport;
 
136
                },
 
137
                getScissor: function ()
 
138
                {
 
139
                        return this .scissor;
 
140
                },
 
141
                intersectsSphere: function (radius, center)
 
142
                {
 
143
                        var planes = this .planes;
 
144
                
 
145
                        if (planes [0] .getDistanceToPoint (center) > radius)
 
146
                                return false;
 
147
 
 
148
                        if (planes [1] .getDistanceToPoint (center) > radius)
 
149
                                return false;
 
150
 
 
151
                        if (planes [2] .getDistanceToPoint (center) > radius)
 
152
                                return false;
 
153
 
 
154
                        if (planes [3] .getDistanceToPoint (center) > radius)
 
155
                                return false;
 
156
 
 
157
                        if (planes [4] .getDistanceToPoint (center) > radius)
 
158
                                return false;
 
159
 
 
160
                        if (planes [5] .getDistanceToPoint (center) > radius)
 
161
                                return false;
 
162
 
 
163
                        return true;
 
164
                },
 
165
        };
 
166
 
 
167
        $.extend (ViewVolume,
 
168
        {
 
169
                unProjectPoint: function (winx, winy, winz, modelViewMatrix, projectionMatrix, viewport, point)
 
170
                {
 
171
                        matrix .assign (modelViewMatrix) .multRight (projectionMatrix) .inverse ();
 
172
 
 
173
                        return this .unProjectPointMatrix (winx, winy, winz, matrix, viewport, point);
 
174
                },
 
175
                unProjectPointMatrix: function (winx, winy, winz, invModelViewProjection, viewport, point)
 
176
                {
 
177
                        // Transformation of normalized coordinates between -1 and 1
 
178
                        vin .set ((winx - viewport [0]) / viewport [2] * 2 - 1,
 
179
                                  (winy - viewport [1]) / viewport [3] * 2 - 1,
 
180
                                  2 * winz - 1,
 
181
                                  1);
 
182
 
 
183
                        //Objects coordinates
 
184
                        invModelViewProjection .multVecMatrix (vin);
 
185
 
 
186
                        if (vin .w === 0)
 
187
                                throw new Error ("Couldn't unproject point: divisor is 0.");
 
188
 
 
189
                        var d = 1 / vin .w;
 
190
 
 
191
                        return point .set (vin .x * d, vin .y * d, vin .z * d);
 
192
                },
 
193
                unProjectRay: function (winx, winy, modelViewMatrix, projectionMatrix, viewport, result)
 
194
                {
 
195
                        matrix .assign (modelViewMatrix) .multRight (projectionMatrix) .inverse ();
 
196
 
 
197
                        ViewVolume .unProjectPointMatrix (winx, winy, 0.0, matrix, viewport, near);
 
198
                        ViewVolume .unProjectPointMatrix (winx, winy, 0.9, matrix, viewport, far);
 
199
 
 
200
                        return result .setPoints (near, far);
 
201
                },
 
202
                projectPoint: function (point, modelViewMatrix, projectionMatrix, viewport, vout)
 
203
                {
 
204
                        vin .set (point .x, point .y, point .z, 1);
 
205
 
 
206
                        projectionMatrix .multVecMatrix (modelViewMatrix .multVecMatrix (vin));
 
207
 
 
208
                        if (vin .w === 0)
 
209
                                throw new Error ("Couldn't project point: divisor is 0.");
 
210
 
 
211
                        var d = 1 / (2 * vin .w);
 
212
 
 
213
                        return vout .set ((vin .x * d + 0.5) * viewport [2] + viewport [0],
 
214
                                          (vin .y * d + 0.5) * viewport [3] + viewport [1],
 
215
                                          (vin .z * d + 0.5));
 
216
                },
 
217
                projectLine: function (line, modelViewMatrix, projectionMatrix, viewport, result)
 
218
                {
 
219
                        ViewVolume .projectPoint (line .point, modelViewMatrix, projectionMatrix, viewport, near);
 
220
                        ViewVolume .projectPoint (Vector3 .multiply (line .direction, 1e9) .add (line .point), modelViewMatrix, projectionMatrix, viewport, far);
 
221
 
 
222
                        near .z = 0;
 
223
                        far  .z = 0;
 
224
 
 
225
                        return result .setPoints (near, far);
 
226
                },
 
227
        });
 
228
 
 
229
        return ViewVolume;
 
230
});