AERA
operators.cpp
1 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
2 //_/_/
3 //_/_/ AERA
4 //_/_/ Autocatalytic Endogenous Reflective Architecture
5 //_/_/
6 //_/_/ Copyright (c) 2018-2025 Jeff Thompson
7 //_/_/ Copyright (c) 2018-2025 Kristinn R. Thorisson
8 //_/_/ Copyright (c) 2018-2025 Icelandic Institute for Intelligent Machines
9 //_/_/ Copyright (c) 2023 Leonard Eberding
10 //_/_/ http://www.iiim.is
11 //_/_/
12 //_/_/ Copyright (c) 2010-2012 Eric Nivel
13 //_/_/ Center for Analysis and Design of Intelligent Agents
14 //_/_/ Reykjavik University, Menntavegur 1, 102 Reykjavik, Iceland
15 //_/_/ http://cadia.ru.is
16 //_/_/
17 //_/_/ Part of this software was developed by Eric Nivel
18 //_/_/ in the HUMANOBS EU research project, which included
19 //_/_/ the following parties:
20 //_/_/
21 //_/_/ Autonomous Systems Laboratory
22 //_/_/ Technical University of Madrid, Spain
23 //_/_/ http://www.aslab.org/
24 //_/_/
25 //_/_/ Communicative Machines
26 //_/_/ Edinburgh, United Kingdom
27 //_/_/ http://www.cmlabs.com/
28 //_/_/
29 //_/_/ Istituto Dalle Molle di Studi sull'Intelligenza Artificiale
30 //_/_/ University of Lugano and SUPSI, Switzerland
31 //_/_/ http://www.idsia.ch/
32 //_/_/
33 //_/_/ Institute of Cognitive Sciences and Technologies
34 //_/_/ Consiglio Nazionale delle Ricerche, Italy
35 //_/_/ http://www.istc.cnr.it/
36 //_/_/
37 //_/_/ Dipartimento di Ingegneria Informatica
38 //_/_/ University of Palermo, Italy
39 //_/_/ http://diid.unipa.it/roboticslab/
40 //_/_/
41 //_/_/
42 //_/_/ --- HUMANOBS Open-Source BSD License, with CADIA Clause v 1.0 ---
43 //_/_/
44 //_/_/ Redistribution and use in source and binary forms, with or without
45 //_/_/ modification, is permitted provided that the following conditions
46 //_/_/ are met:
47 //_/_/ - Redistributions of source code must retain the above copyright
48 //_/_/ and collaboration notice, this list of conditions and the
49 //_/_/ following disclaimer.
50 //_/_/ - Redistributions in binary form must reproduce the above copyright
51 //_/_/ notice, this list of conditions and the following disclaimer
52 //_/_/ in the documentation and/or other materials provided with
53 //_/_/ the distribution.
54 //_/_/
55 //_/_/ - Neither the name of its copyright holders nor the names of its
56 //_/_/ contributors may be used to endorse or promote products
57 //_/_/ derived from this software without specific prior
58 //_/_/ written permission.
59 //_/_/
60 //_/_/ - CADIA Clause: The license granted in and to the software
61 //_/_/ under this agreement is a limited-use license.
62 //_/_/ The software may not be used in furtherance of:
63 //_/_/ (i) intentionally causing bodily injury or severe emotional
64 //_/_/ distress to any person;
65 //_/_/ (ii) invading the personal privacy or violating the human
66 //_/_/ rights of any person; or
67 //_/_/ (iii) committing or preparing for any act of war.
68 //_/_/
69 //_/_/ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
70 //_/_/ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
71 //_/_/ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
72 //_/_/ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73 //_/_/ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
74 //_/_/ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
75 //_/_/ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
76 //_/_/ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
77 //_/_/ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
78 //_/_/ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
79 //_/_/ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
80 //_/_/ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
81 //_/_/ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
82 //_/_/ OF SUCH DAMAGE.
83 //_/_/
84 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
85 
86 #include "operators.h"
87 
88 #include "../r_exec/init.h"
89 #include "../r_exec/mem.h"
90 
91 static uint16 Vec3Opcode;
92 static uint16 Vec2Opcode;
93 static uint16 VecOpcode;
94 static uint16 QuatOpcode;
95 
96 namespace usr_operators {
97 
98 using r_code::Atom;
99 
101 
102 bool add(const r_exec::Context &context) {
103 
104  r_exec::Context lhs = *context.get_child(1);
105  r_exec::Context rhs = *context.get_child(2);
106 
107  if (lhs[0].asOpcode() == Vec3Opcode && rhs[0].asOpcode() == Vec3Opcode) {
108 
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()));
113  return true;
114  }
115 
116  if (lhs[0].asOpcode() == Vec2Opcode && rhs[0].asOpcode() == Vec2Opcode) {
117 
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()));
121  return true;
122  }
123 
124 
125  if (lhs[0].asOpcode() == VecOpcode && rhs[0].asOpcode() == VecOpcode) {
126 
127  r_exec::Context lhs_vals = *lhs.get_child(1);
128  r_exec::Context rhs_vals = *rhs.get_child(1);
129  if (lhs_vals.get_children_count() == rhs_vals.get_children_count()) {
130 
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));
134 
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()));
138  }
139  return true;
140  }
141  }
142 
143  if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
144 
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()));
150  }
151 
152  context.setAtomicResult(Atom::Nil());
153  return false;
154 }
155 
157 
158 bool sub(const r_exec::Context &context) {
159 
160  r_exec::Context lhs = *context.get_child(1);
161  r_exec::Context rhs = *context.get_child(2);
162 
163  if (lhs[0].asOpcode() == Vec3Opcode && rhs[0].asOpcode() == Vec3Opcode) {
164 
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()));
169  return true;
170  }
171 
172  if (lhs[0].asOpcode() == Vec2Opcode && rhs[0].asOpcode() == Vec2Opcode) {
173 
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()));
177  return true;
178  }
179 
180  if (lhs[0].asOpcode() == VecOpcode && rhs[0].asOpcode() == VecOpcode) {
181 
182  r_exec::Context lhs_vals = *lhs.get_child(1);
183  r_exec::Context rhs_vals = *rhs.get_child(1);
184  if (lhs_vals.get_children_count() == rhs_vals.get_children_count()) {
185 
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));
189 
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()));
193  }
194  return true;
195  }
196  }
197 
198  if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
199 
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()));
205  }
206 
207  context.setAtomicResult(Atom::Nil());
208  return false;
209 }
210 
212 
213 bool mul(const r_exec::Context &context) {
214 
215  r_exec::Context lhs = *context.get_child(1);
216  r_exec::Context rhs = *context.get_child(2);
217 
218  if (lhs[0].isFloat()) {
219 
220  if (rhs[0].asOpcode() == Vec3Opcode) {
221 
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()));
226  return true;
227  }
228 
229  if (rhs[0].asOpcode() == Vec2Opcode) {
230 
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()));
234  return true;
235  }
236 
237  if(rhs[0].asOpcode() == VecOpcode) {
238 
239  r_exec::Context rhs_vals = *rhs.get_child(1);
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));
243 
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()));
247  }
248  return true;
249  }
250  }
251  else if (lhs[0].asOpcode() == Vec3Opcode) {
252 
253  if (rhs[0].isFloat()) {
254 
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()));
259  return true;
260  }
261  }
262  else if (lhs[0].asOpcode() == Vec2Opcode) {
263 
264  if (rhs[0].isFloat()) {
265 
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()));
269  return true;
270  }
271  }
272  else if (lhs[0].asOpcode() == VecOpcode) {
273 
274  if (rhs[0].isFloat()) {
275 
276  r_exec::Context lhs_vals = *lhs.get_child(1);
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));
280 
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()));
284  }
285  return true;
286  }
287  }
288  else if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
289 
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();
294 
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();
299 
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.;
304 
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));
310 
311  return true;
312  }
313  context.setAtomicResult(Atom::Nil());
314  return false;
315 }
316 
318 
319 bool div(const r_exec::Context& context) {
320 
321  r_exec::Context lhs = *context.get_child(1);
322  r_exec::Context rhs = *context.get_child(2);
323 
324  if (lhs[0].asOpcode() == Vec3Opcode) {
325 
326  if (rhs[0].isFloat() && rhs[0].asFloat() != 0) {
327 
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()));
332  return true;
333  }
334  }
335  else if (lhs[0].asOpcode() == Vec2Opcode) {
336 
337  if (rhs[0].isFloat() && rhs[0].asFloat() != 0) {
338 
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()));
342  return true;
343  }
344  }
345  else if (lhs[0].asOpcode() == VecOpcode) {
346 
347  if (rhs[0].isFloat() && rhs[0].asFloat() != 0) {
348 
349  r_exec::Context lhs_vals = *lhs.get_child(1);
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));
353 
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()));
357  }
358  return true;
359  }
360  }
361  else if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
362 
363  //taking the conjugate here.
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();
368 
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();
373 
374  // And take the conjugate again
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.;
379 
380  float32 _1 = w_new < 0 ? -1. : 1.;
381 
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));
387 
388  return true;
389  }
390 
391  context.setAtomicResult(Atom::Nil());
392  return false;
393 }
394 
396 
397 bool dis(const r_exec::Context &context) {
398 
399  r_exec::Context lhs = *context.get_child(1);
400  r_exec::Context rhs = *context.get_child(2);
401 
402  if (lhs[0].asOpcode() == Vec3Opcode && rhs[0].asOpcode() == Vec3Opcode) {
403 
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();
407 
408  float32 norm2 = d1 * d1 + d2 * d2 + d3 * d3;
409  context.setAtomicResult(Atom::Float(sqrt(norm2)));
410  return true;
411  }
412 
413  if (lhs[0].asOpcode() == Vec2Opcode && rhs[0].asOpcode() == Vec2Opcode) {
414 
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();
417 
418  float32 norm2 = d1 * d1 + d2 * d2;
419  context.setAtomicResult(Atom::Float(sqrt(norm2)));
420  return true;
421  }
422 
423  if (lhs[0].asOpcode() == VecOpcode && rhs[0].asOpcode() == VecOpcode) {
424 
425  r_exec::Context lhs_vals = *lhs.get_child(1);
426  r_exec::Context rhs_vals = *rhs.get_child(1);
427  if (lhs_vals.get_children_count() == rhs_vals.get_children_count()) {
428 
429  int dimensionality = lhs_vals.get_children_count();
430  float32 norm2 = 0;
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();
433  norm2 += (d * d);
434  }
435  context.setAtomicResult(Atom::Float(sqrt(norm2)));
436  return true;
437  }
438  }
439 
440  if (lhs[0].asOpcode() == QuatOpcode && rhs[0].asOpcode() == QuatOpcode) {
441 
442 
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();
447 
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();
452 
453  float32 inner_product = x1 * x2 + y1 * y2 + z1 * z2 + w1 * w2;
454  float32 dis = acos(2 * inner_product * inner_product - 1);
455 
456  context.setAtomicResult(Atom::Float(dis));
457 
458  }
459 
460  context.setAtomicResult(Atom::Nil());
461  return false;
462 }
463 
465 
466 }
467 
468 r_code::resized_vector<uint16> Operators::Init(OpcodeRetriever r) {
469 
470  const char* vec3 = "vec3";
471  const char* vec2 = "vec2";
472  const char* vec = "vec";
473  const char* quat = "quat";
474  r_code::resized_vector<uint16> initialized_opcodes;
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));
479 
480  return initialized_opcodes;
481 }
r_code::resized_vector< uint16 >
r_exec::Context
Definition: operator.h:100
r_code::Atom
Definition: atom.h:104