86 #include "operators.h"
88 #include "../r_exec/init.h"
89 #include "../r_exec/mem.h"
91 static uint16 Vec3Opcode;
92 static uint16 Vec2Opcode;
93 static uint16 VecOpcode;
94 static uint16 QuatOpcode;
96 namespace usr_operators {
107 if (lhs[0].asOpcode() == Vec3Opcode && rhs[0].asOpcode() == Vec3Opcode) {
109 context.setCompoundResultHead(Atom::Object(Vec3Opcode, 3));
110 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat() + (*rhs.get_child(1))[0].asFloat()));
111 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat() + (*rhs.get_child(2))[0].asFloat()));
112 context.addCompoundResultPart(Atom::Float((*lhs.get_child(3))[0].asFloat() + (*rhs.get_child(3))[0].asFloat()));
116 if (lhs[0].asOpcode() == Vec2Opcode && rhs[0].asOpcode() == Vec2Opcode) {
118 context.setCompoundResultHead(Atom::Object(Vec2Opcode, 2));
119 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat() + (*rhs.get_child(1))[0].asFloat()));
120 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat() + (*rhs.get_child(2))[0].asFloat()));
125 if (lhs[0].asOpcode() == VecOpcode && rhs[0].asOpcode() == VecOpcode) {
129 if (lhs_vals.get_children_count() == rhs_vals.get_children_count()) {
131 int dimensionality = rhs_vals.get_children_count();
132 uint16 vals_index = 2 + context.setCompoundResultHead(Atom::Object(VecOpcode, 1));
133 context.addCompoundResultPart(Atom::IPointer(vals_index));
135 context.addCompoundResultPart(Atom::Set(dimensionality));
136 for (
int i = 1; i <= dimensionality; ++i) {
137 context.addCompoundResultPart(Atom::Float((*lhs_vals.get_child(i))[0].asFloat() + (*rhs_vals.get_child(i))[0].asFloat()));
143 if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
145 context.setCompoundResultHead(Atom::Object(QuatOpcode, 4));
146 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat() + (*rhs.get_child(1))[0].asFloat()));
147 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat() + (*rhs.get_child(2))[0].asFloat()));
148 context.addCompoundResultPart(Atom::Float((*lhs.get_child(3))[0].asFloat() + (*rhs.get_child(3))[0].asFloat()));
149 context.addCompoundResultPart(Atom::Float((*lhs.get_child(4))[0].asFloat() + (*rhs.get_child(4))[0].asFloat()));
152 context.setAtomicResult(Atom::Nil());
163 if (lhs[0].asOpcode() == Vec3Opcode && rhs[0].asOpcode() == Vec3Opcode) {
165 context.setCompoundResultHead(Atom::Object(Vec3Opcode, 3));
166 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat() - (*rhs.get_child(1))[0].asFloat()));
167 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat() - (*rhs.get_child(2))[0].asFloat()));
168 context.addCompoundResultPart(Atom::Float((*lhs.get_child(3))[0].asFloat() - (*rhs.get_child(3))[0].asFloat()));
172 if (lhs[0].asOpcode() == Vec2Opcode && rhs[0].asOpcode() == Vec2Opcode) {
174 context.setCompoundResultHead(Atom::Object(Vec2Opcode, 2));
175 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat() - (*rhs.get_child(1))[0].asFloat()));
176 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat() - (*rhs.get_child(2))[0].asFloat()));
180 if (lhs[0].asOpcode() == VecOpcode && rhs[0].asOpcode() == VecOpcode) {
184 if (lhs_vals.get_children_count() == rhs_vals.get_children_count()) {
186 int dimensionality = rhs_vals.get_children_count();
187 uint16 vals_index = 2 + context.setCompoundResultHead(Atom::Object(VecOpcode, 1));
188 context.addCompoundResultPart(Atom::IPointer(vals_index));
190 context.addCompoundResultPart(Atom::Set(dimensionality));
191 for (
int i = 1; i <= dimensionality; ++i) {
192 context.addCompoundResultPart(Atom::Float((*lhs_vals.get_child(i))[0].asFloat() - (*rhs_vals.get_child(i))[0].asFloat()));
198 if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
200 context.setCompoundResultHead(Atom::Object(QuatOpcode, 4));
201 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat() - (*rhs.get_child(1))[0].asFloat()));
202 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat() - (*rhs.get_child(2))[0].asFloat()));
203 context.addCompoundResultPart(Atom::Float((*lhs.get_child(3))[0].asFloat() - (*rhs.get_child(3))[0].asFloat()));
204 context.addCompoundResultPart(Atom::Float((*lhs.get_child(4))[0].asFloat() - (*rhs.get_child(4))[0].asFloat()));
207 context.setAtomicResult(Atom::Nil());
218 if (lhs[0].isFloat()) {
220 if (rhs[0].asOpcode() == Vec3Opcode) {
222 context.setCompoundResultHead(Atom::Object(Vec3Opcode, 3));
223 context.addCompoundResultPart(Atom::Float(lhs[0].asFloat()*(*rhs.get_child(1))[0].asFloat()));
224 context.addCompoundResultPart(Atom::Float(lhs[0].asFloat()*(*rhs.get_child(2))[0].asFloat()));
225 context.addCompoundResultPart(Atom::Float(lhs[0].asFloat()*(*rhs.get_child(3))[0].asFloat()));
229 if (rhs[0].asOpcode() == Vec2Opcode) {
231 context.setCompoundResultHead(Atom::Object(Vec2Opcode, 2));
232 context.addCompoundResultPart(Atom::Float(lhs[0].asFloat() * (*rhs.get_child(1))[0].asFloat()));
233 context.addCompoundResultPart(Atom::Float(lhs[0].asFloat() * (*rhs.get_child(2))[0].asFloat()));
237 if(rhs[0].asOpcode() == VecOpcode) {
240 int dimensionality = rhs_vals.get_children_count();
241 uint16 vals_index = 2 + context.setCompoundResultHead(Atom::Object(VecOpcode, 1));
242 context.addCompoundResultPart(Atom::IPointer(vals_index));
244 context.addCompoundResultPart(Atom::Set(dimensionality));
245 for (
int i = 1; i <= dimensionality; ++i) {
246 context.addCompoundResultPart(Atom::Float(lhs[0].asFloat() * (*rhs_vals.get_child(i))[0].asFloat()));
251 else if (lhs[0].asOpcode() == Vec3Opcode) {
253 if (rhs[0].isFloat()) {
255 context.setCompoundResultHead(Atom::Object(Vec3Opcode, 3));
256 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat()*rhs[0].asFloat()));
257 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat()*rhs[0].asFloat()));
258 context.addCompoundResultPart(Atom::Float((*lhs.get_child(3))[0].asFloat()*rhs[0].asFloat()));
262 else if (lhs[0].asOpcode() == Vec2Opcode) {
264 if (rhs[0].isFloat()) {
266 context.setCompoundResultHead(Atom::Object(Vec2Opcode, 2));
267 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat() * rhs[0].asFloat()));
268 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat() * rhs[0].asFloat()));
272 else if (lhs[0].asOpcode() == VecOpcode) {
274 if (rhs[0].isFloat()) {
277 int dimensionality = lhs_vals.get_children_count();
278 uint16 vals_index = 2 + context.setCompoundResultHead(Atom::Object(VecOpcode, 1));
279 context.addCompoundResultPart(Atom::IPointer(vals_index));
281 context.addCompoundResultPart(Atom::Set(dimensionality));
282 for (
int i = 1; i <= dimensionality; ++i) {
283 context.addCompoundResultPart(Atom::Float((*lhs_vals.get_child(i))[0].asFloat() * rhs[0].asFloat()));
288 else if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
290 float32 w1 = (*lhs.get_child(1))[0].asFloat();
291 float32 x1 = (*lhs.get_child(2))[0].asFloat();
292 float32 y1 = (*lhs.get_child(3))[0].asFloat();
293 float32 z1 = (*lhs.get_child(4))[0].asFloat();
295 float32 w2 = (*rhs.get_child(1))[0].asFloat();
296 float32 x2 = (*rhs.get_child(2))[0].asFloat();
297 float32 y2 = (*rhs.get_child(3))[0].asFloat();
298 float32 z2 = (*rhs.get_child(4))[0].asFloat();
300 float32 w_new = round((-x1 * x2 - y1 * y2 - z1 * z2 + w1 * w2) * 100.) / 100.;
301 float32 x_new = round(( x1 * w2 + y1 * z2 - z1 * y2 + w1 * x2) * 100.) / 100.;
302 float32 y_new = round((-x1 * z2 + y1 * w2 + z1 * x2 + w1 * y2) * 100.) / 100.;
303 float32 z_new = round(( x1 * y2 - y1 * x2 + z1 * w2 + w1 * z2) * 100.) / 100.;
305 context.setCompoundResultHead(Atom::Object(QuatOpcode, 4));
306 context.addCompoundResultPart(Atom::Float(w_new));
307 context.addCompoundResultPart(Atom::Float(x_new));
308 context.addCompoundResultPart(Atom::Float(y_new));
309 context.addCompoundResultPart(Atom::Float(z_new));
313 context.setAtomicResult(Atom::Nil());
324 if (lhs[0].asOpcode() == Vec3Opcode) {
326 if (rhs[0].isFloat() && rhs[0].asFloat() != 0) {
328 context.setCompoundResultHead(Atom::Object(Vec3Opcode, 3));
329 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat() / rhs[0].asFloat()));
330 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat() / rhs[0].asFloat()));
331 context.addCompoundResultPart(Atom::Float((*lhs.get_child(3))[0].asFloat() / rhs[0].asFloat()));
335 else if (lhs[0].asOpcode() == Vec2Opcode) {
337 if (rhs[0].isFloat() && rhs[0].asFloat() != 0) {
339 context.setCompoundResultHead(Atom::Object(Vec2Opcode, 2));
340 context.addCompoundResultPart(Atom::Float((*lhs.get_child(1))[0].asFloat() / rhs[0].asFloat()));
341 context.addCompoundResultPart(Atom::Float((*lhs.get_child(2))[0].asFloat() / rhs[0].asFloat()));
345 else if (lhs[0].asOpcode() == VecOpcode) {
347 if (rhs[0].isFloat() && rhs[0].asFloat() != 0) {
350 int dimensionality = lhs_vals.get_children_count();
351 uint16 vals_index = 2 + context.setCompoundResultHead(Atom::Object(VecOpcode, 1));
352 context.addCompoundResultPart(Atom::IPointer(vals_index));
354 context.addCompoundResultPart(Atom::Set(dimensionality));
355 for (
int i = 1; i <= dimensionality; ++i) {
356 context.addCompoundResultPart(Atom::Float((*lhs_vals.get_child(i))[0].asFloat() / rhs[0].asFloat()));
361 else if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
364 float32 w1 = (*lhs.get_child(1))[0].asFloat();
365 float32 x1 = -(*lhs.get_child(2))[0].asFloat();
366 float32 y1 = -(*lhs.get_child(3))[0].asFloat();
367 float32 z1 = -(*lhs.get_child(4))[0].asFloat();
369 float32 w2 = (*rhs.get_child(1))[0].asFloat();
370 float32 x2 = (*rhs.get_child(2))[0].asFloat();
371 float32 y2 = (*rhs.get_child(3))[0].asFloat();
372 float32 z2 = (*rhs.get_child(4))[0].asFloat();
375 float32 w_new = round((-x1 * x2 - y1 * y2 - z1 * z2 + w1 * w2) * 100.) / 100.;
376 float32 x_new = -round((x1 * w2 + y1 * z2 - z1 * y2 + w1 * x2) * 100.) / 100.;
377 float32 y_new = -round((-x1 * z2 + y1 * w2 + z1 * x2 + w1 * y2) * 100.) / 100.;
378 float32 z_new = -round((x1 * y2 - y1 * x2 + z1 * w2 + w1 * z2) * 100.) / 100.;
380 float32 _1 = w_new < 0 ? -1. : 1.;
382 context.setCompoundResultHead(Atom::Object(QuatOpcode, 4));
383 context.addCompoundResultPart(Atom::Float(_1 * w_new));
384 context.addCompoundResultPart(Atom::Float(_1 * x_new));
385 context.addCompoundResultPart(Atom::Float(_1 * y_new));
386 context.addCompoundResultPart(Atom::Float(_1 * z_new));
391 context.setAtomicResult(Atom::Nil());
402 if (lhs[0].asOpcode() == Vec3Opcode && rhs[0].asOpcode() == Vec3Opcode) {
404 float32 d1 = (*lhs.get_child(1))[0].asFloat() - (*rhs.get_child(1))[0].asFloat();
405 float32 d2 = (*lhs.get_child(2))[0].asFloat() - (*rhs.get_child(2))[0].asFloat();
406 float32 d3 = (*lhs.get_child(3))[0].asFloat() - (*rhs.get_child(3))[0].asFloat();
408 float32 norm2 = d1 * d1 + d2 * d2 + d3 * d3;
409 context.setAtomicResult(Atom::Float(sqrt(norm2)));
413 if (lhs[0].asOpcode() == Vec2Opcode && rhs[0].asOpcode() == Vec2Opcode) {
415 float32 d1 = (*lhs.get_child(1))[0].asFloat() - (*rhs.get_child(1))[0].asFloat();
416 float32 d2 = (*lhs.get_child(2))[0].asFloat() - (*rhs.get_child(2))[0].asFloat();
418 float32 norm2 = d1 * d1 + d2 * d2;
419 context.setAtomicResult(Atom::Float(sqrt(norm2)));
423 if (lhs[0].asOpcode() == VecOpcode && rhs[0].asOpcode() == VecOpcode) {
427 if (lhs_vals.get_children_count() == rhs_vals.get_children_count()) {
429 int dimensionality = lhs_vals.get_children_count();
431 for (
int i = 1; i <= dimensionality; ++i) {
432 float32 d = (*lhs_vals.get_child(i))[0].asFloat() - (*rhs_vals.get_child(i))[0].asFloat();
435 context.setAtomicResult(Atom::Float(sqrt(norm2)));
440 if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
443 float32 w1 = (*lhs.get_child(1))[0].asFloat();
444 float32 x1 = (*lhs.get_child(2))[0].asFloat();
445 float32 y1 = (*lhs.get_child(3))[0].asFloat();
446 float32 z1 = (*lhs.get_child(4))[0].asFloat();
448 float32 w2 = (*rhs.get_child(1))[0].asFloat();
449 float32 x2 = (*rhs.get_child(2))[0].asFloat();
450 float32 y2 = (*rhs.get_child(3))[0].asFloat();
451 float32 z2 = (*rhs.get_child(4))[0].asFloat();
453 float32 inner_product = x1 * x2 + y1 * y2 + z1 * z2 + w1 * w2;
454 float32 dis = acos(2 * inner_product * inner_product - 1);
456 context.setAtomicResult(Atom::Float(dis));
460 context.setAtomicResult(Atom::Nil());
470 const char* vec3 =
"vec3";
471 const char* vec2 =
"vec2";
472 const char* vec =
"vec";
473 const char* quat =
"quat";
475 initialized_opcodes.push_back(Vec3Opcode = r(vec3));
476 initialized_opcodes.push_back(Vec2Opcode = r(vec2));
477 initialized_opcodes.push_back(VecOpcode = r(vec));
478 initialized_opcodes.push_back(QuatOpcode = r(quat));
480 return initialized_opcodes;