~holger-seelig/cobweb.js/trunk

« back to all changes in this revision

Viewing changes to cobweb.js/cobweb/Components/ParticleSystems/SurfaceEmitter.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
 
        "cobweb/Fields",
53
 
        "cobweb/Basic/X3DFieldDefinition",
54
 
        "cobweb/Basic/FieldDefinitionArray",
55
 
        "cobweb/Components/ParticleSystems/X3DParticleEmitterNode",
56
 
        "cobweb/Bits/X3DConstants",
57
 
        "cobweb/Bits/X3DCast",
58
 
        "standard/Math/Geometry/Triangle3",
59
 
        "standard/Math/Numbers/Vector3",
60
 
        "standard/Math/Algorithm",
61
 
],
62
 
function ($,
63
 
          Fields,
64
 
          X3DFieldDefinition,
65
 
          FieldDefinitionArray,
66
 
          X3DParticleEmitterNode, 
67
 
          X3DConstants,
68
 
          X3DCast,
69
 
          Triangle3,
70
 
          Vector3,
71
 
          Algorithm)
72
 
{
73
 
"use strict";
74
 
 
75
 
        var
76
 
                vertex1  = new Vector3 (0, 0, 0),
77
 
                vertex2  = new Vector3 (0, 0, 0),
78
 
                vertex3  = new Vector3 (0, 0, 0),
79
 
                direction = new Vector3 (0, 0, 0);
80
 
 
81
 
        function SurfaceEmitter (executionContext)
82
 
        {
83
 
                X3DParticleEmitterNode .call (this, executionContext);
84
 
 
85
 
                this .addType (X3DConstants .SurfaceEmitter);
86
 
 
87
 
                this .surfaceNode    = null;
88
 
                this .areaSoFarArray = [ 0 ];
89
 
        }
90
 
 
91
 
        SurfaceEmitter .prototype = $.extend (Object .create (X3DParticleEmitterNode .prototype),
92
 
        {
93
 
                constructor: SurfaceEmitter,
94
 
                fieldDefinitions: new FieldDefinitionArray ([
95
 
                        new X3DFieldDefinition (X3DConstants .inputOutput,    "metadata",    new Fields .SFNode ()),
96
 
                        new X3DFieldDefinition (X3DConstants .inputOutput,    "speed",       new Fields .SFFloat ()),
97
 
                        new X3DFieldDefinition (X3DConstants .inputOutput,    "variation",   new Fields .SFFloat (0.25)),
98
 
                        new X3DFieldDefinition (X3DConstants .initializeOnly, "mass",        new Fields .SFFloat ()),
99
 
                        new X3DFieldDefinition (X3DConstants .initializeOnly, "surfaceArea", new Fields .SFFloat ()),
100
 
                        new X3DFieldDefinition (X3DConstants .initializeOnly, "surface",     new Fields .SFNode ()),
101
 
                ]),
102
 
                getTypeName: function ()
103
 
                {
104
 
                        return "SurfaceEmitter";
105
 
                },
106
 
                getComponentName: function ()
107
 
                {
108
 
                        return "ParticleSystems";
109
 
                },
110
 
                getContainerField: function ()
111
 
                {
112
 
                        return "emitter";
113
 
                },
114
 
                initialize: function ()
115
 
                {
116
 
                        X3DParticleEmitterNode .prototype .initialize .call (this);
117
 
 
118
 
                        this .surface_ .addInterest ("set_surface__", this);
119
 
 
120
 
                        this .set_surface__ ();
121
 
                },
122
 
                set_surface__: function ()
123
 
                {
124
 
                        if (this .surfaceNode)
125
 
                                this .surfaceNode .removeInterest ("set_geometry__", this);
126
 
 
127
 
                        this .surfaceNode = X3DCast (X3DConstants .X3DGeometryNode, this .surface_);
128
 
 
129
 
                        if (this .surfaceNode)
130
 
                                this .surfaceNode .addInterest ("set_geometry__", this);
131
 
 
132
 
                        this .set_geometry__ ();
133
 
                },
134
 
                set_geometry__: function ()
135
 
                {
136
 
                        if (this .surfaceNode)
137
 
                        {               
138
 
                                delete this .getRandomPosition;
139
 
                                delete this .getRandomVelocity;
140
 
 
141
 
                                var
142
 
                                        areaSoFar      = 0,
143
 
                                        areaSoFarArray = this .areaSoFarArray,
144
 
                                        vertices       = this .surfaceNode .getVertices ();
145
 
                
146
 
                                areaSoFarArray .length = 1;
147
 
 
148
 
                                for (var i = 0, length = vertices .length; i < length; i += 12)
149
 
                                {
150
 
                                        vertex1 .set (vertices [i + 0], vertices [i + 1], vertices [i + 2]);
151
 
                                        vertex2 .set (vertices [i + 4], vertices [i + 5], vertices [i + 6]);
152
 
                                        vertex3 .set (vertices [i + 8], vertices [i + 9], vertices [i + 10]);
153
 
 
154
 
                                        areaSoFar += Triangle3 .area (vertex1, vertex2, vertex3);
155
 
                                        areaSoFarArray .push (areaSoFar);
156
 
                                }
157
 
                        }
158
 
                        else
159
 
                        {
160
 
                                this .getRandomPosition = getPosition;
161
 
                                this .getRandomVelocity = this .getSphericalRandomVelocity;
162
 
 
163
 
                                direction .set (0, 0, 0);
164
 
                        }
165
 
                },
166
 
                getRandomPosition: function (position)
167
 
                {
168
 
                        // Determine index0.
169
 
 
170
 
                        var
171
 
                                areaSoFarArray = this .areaSoFarArray,
172
 
                                length         = areaSoFarArray .length,
173
 
                                fraction       = Math .random () * areaSoFarArray [length - 1],
174
 
                                index0         = 0
175
 
 
176
 
                        if (length == 1 || fraction <= areaSoFarArray [0])
177
 
                        {
178
 
                                index0 = 0;
179
 
                        }
180
 
                        else if (fraction >= areaSoFarArray [length - 1])
181
 
                        {
182
 
                                index0 = length - 2;
183
 
                        }
184
 
                        else
185
 
                        {
186
 
                                var index = Algorithm .upperBound (areaSoFarArray, 0, length, fraction, Algorithm .less);
187
 
 
188
 
                                if (index < length)
189
 
                                {
190
 
                                        index0 = index - 1;
191
 
                                }
192
 
                                else
193
 
                                {
194
 
                                        index0 = 0;
195
 
                                }
196
 
                        }
197
 
 
198
 
                        // Random barycentric coordinates.
199
 
 
200
 
                        var
201
 
                                u = Math .random (),
202
 
                                v = Math .random ();
203
 
                
204
 
                        if (u + v > 1)
205
 
                        {
206
 
                                u = 1 - u;
207
 
                                v = 1 - v;
208
 
                        }
209
 
 
210
 
                        // Interpolate and set position.
211
 
 
212
 
                        var
213
 
                                i        = index0 * 12,
214
 
                                vertices = this .surfaceNode .getVertices ();
215
 
 
216
 
                        var t = 1 - u - v;
217
 
 
218
 
                        position .x = u * vertices [i + 0] + v * vertices [i + 4] + t * vertices [i + 8];
219
 
                        position .y = u * vertices [i + 1] + v * vertices [i + 5] + t * vertices [i + 9];
220
 
                        position .z = u * vertices [i + 2] + v * vertices [i + 6] + t * vertices [i + 10];
221
 
 
222
 
                        var
223
 
                                i       = index0 * 9,
224
 
                                normals = this .surfaceNode .getNormals ();
225
 
 
226
 
                        direction .x = u * normals [i + 0] + v * normals [i + 3] + t * normals [i + 6];
227
 
                        direction .y = u * normals [i + 1] + v * normals [i + 4] + t * normals [i + 7];
228
 
                        direction .z = u * normals [i + 2] + v * normals [i + 5] + t * normals [i + 8];
229
 
 
230
 
                        return position;
231
 
                },
232
 
                getRandomVelocity: function (velocity)
233
 
                {
234
 
                        var speed = this .getRandomSpeed ();
235
 
 
236
 
                        velocity .x = direction .x * speed;
237
 
                        velocity .y = direction .y * speed;
238
 
                        velocity .z = direction .z * speed;
239
 
 
240
 
                        return velocity;
241
 
                },
242
 
        });
243
 
 
244
 
        function getPosition (position)
245
 
        {
246
 
                return position .set (0, 0, 0);
247
 
        }
248
 
 
249
 
        return SurfaceEmitter;
250
 
});
251
 
 
252