1
/* -*- Mode: JavaScript; coding: utf-8; tab-width: 3; indent-tabs-mode: tab; c-basic-offset: 3 -*-
2
*******************************************************************************
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6
* Copyright create3000, Scheffelstraße 31a, Leipzig, Germany 2011.
8
* All rights reserved. Holger Seelig <holger.seelig@yahoo.de>.
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
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.
19
* NON-MILITARY USE ONLY
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.
26
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
28
* Copyright 2015, 2016 Holger Seelig <holger.seelig@yahoo.de>.
30
* This file is part of the Cobweb Project.
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.
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).
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.
45
* For Silvio, Joy and Adi.
47
******************************************************************************/
52
"cobweb/Components/Rendering/X3DGeometryNode",
53
"cobweb/Bits/X3DCast",
54
"cobweb/Bits/X3DConstants",
55
"standard/Math/Numbers/Vector3",
65
function X3DComposedGeometryNode (executionContext)
67
X3DGeometryNode .call (this, executionContext);
69
this .addType (X3DConstants .X3DComposedGeometryNode);
71
this .colorNode = null;
72
this .texCoordNode = null;
73
this .normalNode = null;
74
this .coordNode = null;
77
X3DComposedGeometryNode .prototype = $.extend (Object .create (X3DGeometryNode .prototype),
79
constructor: X3DComposedGeometryNode,
80
initialize: function ()
82
X3DGeometryNode .prototype .initialize .call (this);
84
this .attrib_ .addInterest ("set_attrib__", this);
85
this .color_ .addInterest ("set_color__", this);
86
this .texCoord_ .addInterest ("set_texCoord__", this);
87
this .normal_ .addInterest ("set_normal__", this);
88
this .coord_ .addInterest ("set_coord__", this);
90
this .set_attrib__ ();
92
this .set_texCoord__ ();
93
this .set_normal__ ();
98
return this .colorNode;
100
getTexCoord: function ()
102
return this .texCoordNode;
104
getNormal: function ()
106
return this .normalNode;
108
getCoord: function ()
110
return this .coordNode;
112
set_attrib__: function ()
114
var attribNodes = this .getAttrib ();
116
for (var i = 0, length = attribNodes .length; i < length; ++ i)
117
attribNodes [i] .removeInterest ("addNodeEvent", this);
119
attribNodes .length = 0;
121
for (var i = 0, length = this .attrib_ .length; i < length; ++ i)
123
var attribNode = X3DCast (X3DConstants .X3DVertexAttributeNode, this .attrib_ [i]);
126
attribNodes .push (attribNode);
129
for (var i = 0; i < this .attribNodes .length; ++ i)
130
attribNodes [i] .addInterest ("addNodeEvent", this);
132
set_color__: function ()
136
this .colorNode .removeInterest ("addNodeEvent", this);
137
this .colorNode .removeInterest ("set_transparent__", this);
140
this .colorNode = X3DCast (X3DConstants .X3DColorNode, this .color_);
144
this .colorNode .addInterest ("addNodeEvent", this);
145
this .colorNode .addInterest ("set_transparent__", this);
147
this .set_transparent__ ();
150
this .transparent_ = false;
152
set_transparent__: function ()
154
this .transparent_ = this .colorNode .isTransparent ();
156
set_texCoord__: function ()
158
if (this .texCoordNode)
159
this .texCoordNode .removeInterest ("addNodeEvent", this);
161
this .texCoordNode = X3DCast (X3DConstants .X3DTextureCoordinateNode, this .texCoord_);
163
if (this .texCoordNode)
164
this .texCoordNode .addInterest ("addNodeEvent", this);
166
this .setCurrentTexCoord (this .texCoordNode);
168
set_normal__: function ()
170
if (this .normalNode)
171
this .normalNode .removeInterest ("addNodeEvent", this);
173
this .normalNode = X3DCast (X3DConstants .X3DNormalNode, this .normal_);
175
if (this .normalNode)
176
this .normalNode .addInterest ("addNodeEvent", this);
178
set_coord__: function ()
181
this .coordNode .removeInterest ("addNodeEvent", this);
183
this .coordNode = X3DCast (X3DConstants .X3DCoordinateNode, this .coord_);
186
this .coordNode .addInterest ("addNodeEvent", this);
188
getPolygonIndex: function (index)
192
getTriangleIndex: function (index)
196
build: function (verticesPerPolygon, polygonsSize, verticesPerFace, trianglesSize)
198
if (! this .coordNode || this .coordNode .isEmpty ())
201
// Set size to a multiple of verticesPerPolygon.
203
polygonsSize -= polygonsSize % verticesPerPolygon;
204
trianglesSize -= trianglesSize % verticesPerFace;
207
colorPerVertex = this .colorPerVertex_ .getValue (),
208
normalPerVertex = this .normalPerVertex_ .getValue (),
209
attribNodes = this .getAttrib (),
210
numAttrib = attribNodes .length,
211
attribs = this .getAttribs (),
212
colorNode = this .getColor (),
213
texCoordNode = this .getTexCoord (),
214
normalNode = this .getNormal (),
215
coordNode = this .getCoord (),
216
textCoords = this .getTexCoords (),
220
texCoordNode .init (textCoords);
224
for (var i = 0; i < trianglesSize; ++ i)
226
face = Math .floor (i / verticesPerFace);
228
var index = this .getPolygonIndex (this .getTriangleIndex (i));
230
for (var a = 0; a < numAttrib; ++ a)
231
attrib [a] .addValue (attribs [a], index);
236
this .addColor (colorNode .get1Color (index));
238
this .addColor (colorNode .get1Color (face));
242
texCoordNode .addTexCoord (textCoords, index);
247
this .addNormal (normalNode .get1Vector (index));
250
this .addNormal (normalNode .get1Vector (face));
253
this .addVertex (coordNode .get1Point (index));
256
// Autogenerate normal if not specified.
258
if (! this .getNormal ())
259
this .buildNormals (verticesPerPolygon, polygonsSize, trianglesSize);
261
this .setSolid (this .solid_ .getValue ());
262
this .setCCW (this .ccw_ .getValue ());
264
buildNormals: function (verticesPerPolygon, polygonsSize, trianglesSize)
266
var normals = this .createNormals (verticesPerPolygon, polygonsSize);
268
for (var i = 0; i < trianglesSize; ++ i)
269
this .addNormal (normals [this .getTriangleIndex (i)]);
271
createNormals: function (verticesPerPolygon, polygonsSize)
273
var normals = this .createFaceNormals (verticesPerPolygon, polygonsSize);
275
if (this .normalPerVertex_ .getValue ())
277
var normalIndex = [ ];
279
for (var i = 0; i < polygonsSize; ++ i)
281
var index = this .getPolygonIndex (i);
283
if (! normalIndex [index])
284
normalIndex [index] = [ ];
286
normalIndex [index] .push (i);
289
return this .refineNormals (normalIndex, normals, Math .PI);
294
createFaceNormals: function (verticesPerPolygon, polygonsSize)
297
cw = ! this .ccw_ .getValue (),
298
coord = this .coordNode,
301
for (var i = 0; i < polygonsSize; i += verticesPerPolygon)
303
var normal = this .getPolygonNormal (verticesPerPolygon, coord);
308
for (var n = 0; n < verticesPerPolygon; ++ n)
309
normals .push (normal);
314
getPolygonNormal: function (verticesPerPolygon, coord)
316
// Determine polygon normal.
317
// We use Newell's method https://www.opengl.org/wiki/Calculating_a_Surface_Normal here:
320
normal = new Vector3 (0, 0, 0),
321
next = coord .get1Point (this .getPolygonIndex (0));
323
for (var i = 0; i < verticesPerPolygon; ++ i)
327
next = coord .get1Point (this .getPolygonIndex ((i + 1) % verticesPerPolygon));
329
normal .x += (current .y - next .y) * (current .z + next .z);
330
normal .y += (current .z - next .z) * (current .x + next .x);
331
normal .z += (current .x - next .x) * (current .y + next .y);
334
return normal .normalize ();
338
return X3DComposedGeometryNode;