forked from xml3d/xml3d.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvec3.js
More file actions
236 lines (213 loc) · 8.03 KB
/
vec3.js
File metadata and controls
236 lines (213 loc) · 8.03 KB
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
// XML3DVec3
(function($) {
// Is native?
if($) return;
/**
* Configure array properties
* @private
* @this {XML3DVec3}
* @param {number} index Array index
*/
function prop(index) {
return {
get : function() {
return this._data[index];
},
set : function(val) {
this._data[index] = val;
// Value changed
if (this._callback)
this._callback(this);
},
configurable : false,
enumerable : false
};
};
/**
* Creates an instance of XML3DVec3. XML3DVec3 represents a
* three-dimensional vector as a 3-tuple floating point values.
* @constructor
* @this {XML3DVec3}
* @param {number=} x The x value (optional). Default: 0.
* @param {number=} y The y value (optional). Default: 0.
* @param {number=} z The z value (optional). Default: 0.
* @param {function(XML3DVec3=)=} cb Called, if value has changed.
* Has this as first parameter.
*/
var XML3DVec3 = function(x, y, z, cb) {
/** @private */
this._data = new Float32Array(3);
if(x !== undefined && x !== null) {
this.set(x,y,z);
}
this._callback = typeof cb == 'function' ? cb : 0;
}, p = XML3DVec3.prototype;
/**
* The set method copies the values from other.
* @param {Object|number} other another XML3DVec3, Float32Array or a number. In the last case the other args are considered, too.
* @param {number=} y
* @param {number=} z
*/
p.set = function(other,y,z) {
if(other.length && other.length >= 3) {
this._data[0] = other[0];
this._data[1] = other[1];
this._data[2] = other[2];
}
else if(other._data && other._data.length && other._data.length === 3) {
this._data[0] = other._data[0];
this._data[1] = other._data[1];
this._data[2] = other._data[2];
} else if(arguments.length == 3) {
this._data[0] = other;
this._data[1] = y;
this._data[2] = z;
}
if (this._callback)
this._callback(this);
};
/** @type {number} */
Object.defineProperty(p, "x", prop(0));
/** @type {number} */
Object.defineProperty(p, "y", prop(1));
/** @type {number} */
Object.defineProperty(p, "z", prop(2));
/**
* String representation of the XML3DVec3.
* @override
* @this {XML3DVec3}
* @return {string} Human-readable representation of this XML3DVec3.
*/
p.toString = function() {
return "[object XML3DVec3]";
};
/**
* Returns the component-wise addition of this vector with a second vector
* passed as parameter. Result is a newly created vector. This is not
* modified.
* @param {XML3DVec3} that The vector to add
* @return {XML3DVec3} The new vector with the result of the addition
*/
p.add = function(that) {
if (that._data)
return new XML3DVec3(this._data[0] + that._data[0], this._data[1]
+ that._data[1], this._data[2] + that._data[2]);
return new XML3DVec3(this._data[0] + that.x, this._data[1] + that.y,
this._data[2] + that.z);
};
/**
* Returns the component-wise subtraction of this vector with a second
* vector passed as parameter. Result is a newly created vector. This is not
* modified.
* @param {XML3DVec3} that The vector to subtract
* @return {XML3DVec3} The new vector with the result of the subtraction
*/
p.subtract = function(that) {
if (that._data)
return new XML3DVec3(this._data[0] - that._data[0], this._data[1]
- that._data[1], this._data[2] - that._data[2]);
return new XML3DVec3(this._data[0] - that.x, this._data[1] - that.y,
this._data[2] - that.z);
};
/**
* Returns the length of this vector.
* @return {number} The length of this vector
*/
p.length = function() {
return Math.sqrt((this._data[0] * this._data[0])
+ (this._data[1] * this._data[1])
+ (this._data[2] * this._data[2]));
};
/**
* The setVec3Value method replaces the existing vector with one computed
* from parsing the passed string.
* @param {string} str The string to parse
* @throws {Error} If passed string can not be parsed
*/
p.setVec3Value = function(str) {
var m = /^\s*(\S+)\s+(\S+)\s+(\S+)\s*$/.exec(str);
if (!m) // TODO Throw DOMException
throw Error("Wrong format for XML3DVec3::setVec3Value");
this._data[0] = +m[1];
this._data[1] = +m[2];
this._data[2] = +m[3];
if (this._callback)
this._callback(this);
};
/**
* Returns the component-wise multiplication of this vector with a second
* vector passed as parameter. Result is a newly created vector. This is not
* modified.
* @param {XML3DVec3} that The vector to multiply
* @return {XML3DVec3} The new vector with the result of the multiplication
*/
p.multiply = function(that) {
if (that._data)
return new XML3DVec3(this._data[0] * that._data[0], this._data[1]
* that._data[1], this._data[2] * that._data[2]);
return new XML3DVec3(this._data[0] * that.x, this._data[1] * that.y,
this._data[2] * that.z);
};
/**
* Returns the component-wise multiplication of this vector with a factor
* passed as parameter. Result is a newly created vector. This is not
* modified.
* @param {number} fac The factor for the multiplication
* @return {XML3DVec3} The new and scaled vector
*/
p.scale = function(fac) {
return new XML3DVec3(this._data[0] * fac, this._data[1] * fac,
this._data[2] * fac);
};
/**
* Returns the cross product of this vector with a second vector passed as
* parameter. Result is a newly created vector. This is not modified.
* @param {XML3DVec3} that The second vector
* @return {XML3DVec3} The new vector with the result of the cross product
*/
p.cross = function(that) {
if (that._data)
return new XML3DVec3(this._data[1] * that._data[2] - this._data[2]
* that._data[1], this._data[2] * that._data[0]
- this._data[0] * that._data[2], this._data[0]
* that._data[1] - this._data[1] * that._data[0]);
return new XML3DVec3(this._data[1] * that.z - this._data[2] * that.y,
this._data[2] * that.x - this._data[0] * that.z, this._data[0]
* that.y - this._data[1] * that.x);
};
/**
* Returns the component wise multiplication by -1 of this vector. Result is
* a newly created vector. This is not modified.
* @return {XML3DVec3} The new and negated vector
*/
p.negate = function() {
return new XML3DVec3(-this._data[0], -this._data[1], -this._data[2]);
};
/**
* Returns the dot product of this vector with a second vector passed as
* parameter. This is not modified.
* @param {XML3DVec3} that The second vector
* @return {number} The result of the dot product
*/
p.dot = function(that) {
return (this._data[0] * that.x + this._data[1] * that.y + this._data[2]
* that.z);
};
/**
* Returns the normalized version of this vector. Result is a newly created
* vector. This is not modified.
* @return {XML3DVec3} The new and normalized vector
* @throws {Error} If length of this vector is zero
*/
p.normalize = function() {
var n = this.length();
if (n)
n = 1.0 / n;
else
throw new Error();
return new XML3DVec3(this._data[0] * n, this._data[1] * n,
this._data[2] * n);
};
XML3D.XML3DVec3 = XML3DVec3;
window.XML3DVec3 = XML3DVec3;
}(XML3D._native));