~holger-seelig/cobweb.js/trunk

« back to all changes in this revision

Viewing changes to src/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