summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/Makefile.am3
-rw-r--r--include/compiz-core.h58
-rw-r--r--include/compmatrix.h38
-rw-r--r--include/compoutput.h1
-rw-r--r--include/compscreen.h1
-rw-r--r--include/compvector.h51
-rw-r--r--include/compwindow.h1
-rw-r--r--src/Makefile.am3
-rw-r--r--src/matrix.cpp142
-rw-r--r--src/paint.cpp75
-rw-r--r--src/screen.cpp15
-rw-r--r--src/vector.cpp217
12 files changed, 424 insertions, 181 deletions
diff --git a/include/Makefile.am b/include/Makefile.am
index 6b79d2c..9cb22da 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,7 +1,6 @@
compizincludedir = $(includedir)/compiz
compizinclude_HEADERS = \
compiz.h \
- compiz-plugin.h \
compiz-core.h \
compiz-cube.h \
compiz-scale.h \
@@ -10,4 +9,4 @@ compizinclude_HEADERS = \
nodist_compizinclude_HEADERS = \
compiz-common.h
-DISTCLEANFILES = compiz-common.h \ No newline at end of file
+DISTCLEANFILES = compiz-common.h
diff --git a/include/compiz-core.h b/include/compiz-core.h
index b16b76a..64510ea 100644
--- a/include/compiz-core.h
+++ b/include/compiz-core.h
@@ -257,20 +257,6 @@ eventTerminates (CompDisplay *display,
#define DEG2RAD (M_PI / 180.0f)
-typedef struct _CompTransform {
- float m[16];
-} CompTransform;
-
-typedef union _CompVector {
- float v[4];
- struct {
- float x;
- float y;
- float z;
- float w;
- };
-} CompVector;
-
/* XXX: ScreenPaintAttrib will be removed */
typedef struct _ScreenPaintAttrib {
GLfloat xRotate;
@@ -315,12 +301,6 @@ struct _CompWalker {
};
-/* XXX: prepareXCoords will be removed */
-void
-prepareXCoords (CompScreen *screen,
- CompOutput *output,
- float z);
-
/* screen.c */
@@ -472,44 +452,6 @@ getPluginDisplayIndex (CompDisplay *d,
/* fragment.c */
-
-/* matrix.c */
-
-void
-matrixMultiply (CompTransform *product,
- const CompTransform *transformA,
- const CompTransform *transformB);
-
-void
-matrixMultiplyVector (CompVector *product,
- const CompVector *vector,
- const CompTransform *transform);
-
-void
-matrixVectorDiv (CompVector *v);
-
-void
-matrixRotate (CompTransform *transform,
- float angle,
- float x,
- float y,
- float z);
-
-void
-matrixScale (CompTransform *transform,
- float x,
- float y,
- float z);
-
-void
-matrixTranslate (CompTransform *transform,
- float x,
- float y,
- float z);
-
-void
-matrixGetIdentity (CompTransform *m);
-
/* match.c */
diff --git a/include/compmatrix.h b/include/compmatrix.h
new file mode 100644
index 0000000..71db9ea
--- /dev/null
+++ b/include/compmatrix.h
@@ -0,0 +1,38 @@
+#ifndef _COMPMATRIX_H
+#define _COMPMATRIX_H
+
+#include <compvector.h>
+
+class CompMatrix {
+ public:
+ CompMatrix ();
+
+ const float* getMatrix () const;
+
+ CompMatrix& operator*= (const CompMatrix& rhs);
+
+ void reset ();
+ void toScreenSpace (CompOutput *output, float z);
+
+ void rotate (const float angle, const float x,
+ const float y, const float z);
+ void rotate (const float angle, const CompVector& vector);
+
+ void scale (const float x, const float y, const float z);
+ void scale (const CompVector& vector);
+
+ void translate (const float x, const float y, const float z);
+ void translate (const CompVector& vector);
+
+ private:
+ friend CompMatrix operator* (const CompMatrix& lhs,
+ const CompMatrix& rhs);
+ friend CompVector operator* (const CompMatrix& lhs,
+ const CompVector& rhs);
+
+ float m[16];
+};
+
+typedef CompMatrix CompTransform;
+
+#endif
diff --git a/include/compoutput.h b/include/compoutput.h
index b00e51d..02a618a 100644
--- a/include/compoutput.h
+++ b/include/compoutput.h
@@ -1,6 +1,7 @@
#ifndef _COMPOUTPUT_H
#define _COMPOUTPUT_H
+#include <compiz-core.h>
#include <comprect.h>
class CompOutput : public CompRect {
diff --git a/include/compscreen.h b/include/compscreen.h
index b429c33..36608a9 100644
--- a/include/compscreen.h
+++ b/include/compscreen.h
@@ -4,6 +4,7 @@
#include <compwindow.h>
#include <comptexture.h>
#include <compfragment.h>
+#include <compmatrix.h>
class CompScreen;
class PrivateScreen;
diff --git a/include/compvector.h b/include/compvector.h
new file mode 100644
index 0000000..17e9403
--- /dev/null
+++ b/include/compvector.h
@@ -0,0 +1,51 @@
+#ifndef _COMPVECTOR_H
+#define _COMPVECTOR_H
+
+class CompVector {
+ public:
+ typedef enum {
+ x,
+ y,
+ z,
+ w
+ } VectorCoordsEnum;
+
+ CompVector ();
+ CompVector (float x, float y, float z, float w);
+
+ float& operator[] (int item);
+ float& operator[] (VectorCoordsEnum coord);
+
+ const float operator[] (int item) const;
+ const float operator[] (VectorCoordsEnum coord) const;
+
+ CompVector& operator+= (const CompVector& rhs);
+ CompVector& operator-= (const CompVector& rhs);
+ CompVector& operator*= (const float k);
+ CompVector& operator/= (const float k);
+ CompVector& operator^= (const CompVector& rhs);
+
+ float norm ();
+ CompVector& normalize ();
+
+ private:
+ friend CompVector operator+ (const CompVector& lhs,
+ const CompVector& rhs);
+ friend CompVector operator- (const CompVector& lhs,
+ const CompVector& rhs);
+ friend CompVector operator- (const CompVector& vector);
+ friend float operator* (const CompVector& lhs,
+ const CompVector& rhs);
+ friend CompVector operator* (const float k,
+ const CompVector& vector);
+ friend CompVector operator* (const CompVector& vector,
+ const float k);
+ friend CompVector operator/ (const CompVector& lhs,
+ const CompVector& rhs);
+ friend CompVector operator^ (const CompVector& lhs,
+ const CompVector& rhs);
+
+ float v[4];
+};
+
+#endif
diff --git a/include/compwindow.h b/include/compwindow.h
index 88ede5e..52e3112 100644
--- a/include/compwindow.h
+++ b/include/compwindow.h
@@ -5,6 +5,7 @@
#include <comppoint.h>
#include <comptexture.h>
#include <compfragment.h>
+#include <compmatrix.h>
class CompWindow;
class PrivateWindow;
diff --git a/src/Makefile.am b/src/Makefile.am
index fb72bdc..8f514d4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -35,4 +35,5 @@ compiz_SOURCES = \
size.cpp \
point.cpp \
windowgeometry.cpp \
- icon.cpp
+ icon.cpp \
+ vector.cpp
diff --git a/src/matrix.cpp b/src/matrix.cpp
index 8430f02..7f1c74f 100644
--- a/src/matrix.cpp
+++ b/src/matrix.cpp
@@ -23,13 +23,13 @@
#include <string.h>
#include <math.h>
-
#include <compiz-core.h>
+#include <compmatrix.h>
/**
* Identity matrix.
*/
-static float identity[16] = {
+static const float identity[16] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
@@ -71,48 +71,57 @@ matmul4 (float *product,
}
}
-void
-matrixMultiply (CompTransform *product,
- const CompTransform *transformA,
- const CompTransform *transformB)
+CompMatrix::CompMatrix ()
{
- matmul4 (product->m, transformA->m, transformB->m);
+ memcpy (m, identity, sizeof (m));
}
-/**
- * Multiply the 1x4 vector v with the 4x4 matrix a.
- *
- * \param a matrix.
- * \param v vector.
- * \param product will receive the product of \p a and \p v.
- *
- */
void
-matrixMultiplyVector (CompVector *product,
- const CompVector *vector,
- const CompTransform *transform)
+CompMatrix::reset ()
{
- float vec[4];
- const float *a = transform->m;
- const float *b = vector->v;
- int i;
+ memcpy (m, identity, sizeof (m));
+}
- for (i = 0; i < 4; i++)
- {
- vec[i] = A(i,0) * B(0,0) + A(i,1) * B(1,0) +
- A(i,2) * B(2,0) + A(i,3) * B(3,0);
- }
+const float *
+CompMatrix::getMatrix () const
+{
+ return m;
+}
+
+CompMatrix&
+CompMatrix::operator*= (const CompMatrix& rhs)
+{
+ *this = *this * rhs;
- memcpy (product->v, vec, sizeof (vec));
+ return *this;
}
-void
-matrixVectorDiv (CompVector *vector)
+CompMatrix
+operator* (const CompMatrix& lhs,
+ const CompMatrix& rhs)
{
- int i;
+ CompMatrix result;
+
+ matmul4 (result.m, lhs.m, rhs.m);
+
+ return result;
+}
+
+CompVector
+operator* (const CompMatrix& lhs,
+ const CompVector& rhs)
+{
+ CompVector result;
+ const float *a = lhs.m;
+ int i;
for (i = 0; i < 4; i++)
- vector->v[i] /= vector->v[3];
+ {
+ result[i] = A(i,0) * rhs[0] + A(i,1) * rhs[1] +
+ A(i,2) * rhs[2] + A(i,3) * rhs[3];
+ }
+
+ return result;
}
#undef A
@@ -128,23 +137,23 @@ matrixVectorDiv (CompVector *vector)
* Optimizations contributed by Rudolf Opalla (rudi@khm.de).
*/
void
-matrixRotate (CompTransform *transform,
- float angle,
- float x,
- float y,
- float z)
+CompMatrix::rotate (const float angle,
+ const float xRot,
+ const float yRot,
+ const float zRot)
{
+ float x = xRot, y = yRot, z = zRot;
float xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;
- float m[16];
+ float matrix[16];
Bool optimized;
s = (float) sin (angle * DEG2RAD);
c = (float) cos (angle * DEG2RAD);
- memcpy (m, identity, sizeof (float) * 16);
+ memcpy (matrix, identity, sizeof (matrix));
optimized = FALSE;
-#define M(row, col) m[col * 4 + row]
+#define M(row, col) matrix[col * 4 + row]
if (x == 0.0f)
{
@@ -311,7 +320,17 @@ matrixRotate (CompTransform *transform,
}
#undef M
- matmul4 (transform->m, transform->m, m);
+ matmul4 (m, m, matrix);
+}
+
+void
+CompMatrix::rotate (const float angle,
+ const CompVector& vector)
+{
+ rotate (angle,
+ vector[CompVector::x],
+ vector[CompVector::y],
+ vector[CompVector::z]);
}
/**
@@ -325,19 +344,24 @@ matrixRotate (CompTransform *transform,
* Multiplies in-place the elements of \p matrix by the scale factors.
*/
void
-matrixScale (CompTransform *transform,
- float x,
- float y,
- float z)
+CompMatrix::scale (const float x,
+ const float y,
+ const float z)
{
- float *m = transform->m;
-
m[0] *= x; m[4] *= y; m[8] *= z;
m[1] *= x; m[5] *= y; m[9] *= z;
m[2] *= x; m[6] *= y; m[10] *= z;
m[3] *= x; m[7] *= y; m[11] *= z;
}
+void
+CompMatrix::scale (const CompVector& vector)
+{
+ scale (vector[CompVector::x],
+ vector[CompVector::y],
+ vector[CompVector::z]);
+}
+
/**
* Multiply a matrix with a translation matrix.
*
@@ -349,13 +373,10 @@ matrixScale (CompTransform *transform,
* Adds the translation coordinates to the elements of \p matrix in-place.
*/
void
-matrixTranslate (CompTransform *transform,
- float x,
- float y,
- float z)
+CompMatrix::translate (const float x,
+ const float y,
+ const float z)
{
- float *m = transform->m;
-
m[12] = m[0] * x + m[4] * y + m[8] * z + m[12];
m[13] = m[1] * x + m[5] * y + m[9] * z + m[13];
m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
@@ -363,7 +384,18 @@ matrixTranslate (CompTransform *transform,
}
void
-matrixGetIdentity (CompTransform *transform)
+CompMatrix::translate (const CompVector& vector)
+{
+ translate (vector[CompVector::x],
+ vector[CompVector::y],
+ vector[CompVector::z]);
+}
+
+void
+CompMatrix::toScreenSpace (CompOutput *output,
+ float z)
{
- memcpy (transform->m, identity, sizeof (float) * 16);
+ translate (-0.5f, -0.5f, z);
+ scale (1.0f / output->width (), -1.0f / output->height (), 1.0f);
+ translate (-output->x1 (), -output->y2 (), 0.0f);
}
diff --git a/src/paint.cpp b/src/paint.cpp
index 4cf45c6..f9801fd 100644
--- a/src/paint.cpp
+++ b/src/paint.cpp
@@ -55,50 +55,15 @@ CompScreen::applyTransform (const ScreenPaintAttrib *sAttrib,
{
WRAPABLE_HND_FUNC(applyTransform, sAttrib, output, transform)
- matrixTranslate (transform,
- sAttrib->xTranslate,
- sAttrib->yTranslate,
- sAttrib->zTranslate + sAttrib->zCamera);
- matrixRotate (transform,
- sAttrib->xRotate, 0.0f, 1.0f, 0.0f);
- matrixRotate (transform,
- sAttrib->vRotate,
- cosf (sAttrib->xRotate * DEG2RAD),
- 0.0f,
- sinf (sAttrib->xRotate * DEG2RAD));
- matrixRotate (transform,
- sAttrib->yRotate, 0.0f, 1.0f, 0.0f);
-}
-
-void
-transformToScreenSpace (CompScreen *screen,
- CompOutput *output,
- float z,
- CompTransform *transform)
-{
- matrixTranslate (transform, -0.5f, -0.5f, z);
- matrixScale (transform,
- 1.0f / output->width (),
- -1.0f / output->height (),
- 1.0f);
- matrixTranslate (transform,
- -output->x1 (),
- -output->y2 (),
- 0.0f);
-}
-
-void
-prepareXCoords (CompScreen *screen,
- CompOutput *output,
- float z)
-{
- glTranslatef (-0.5f, -0.5f, z);
- glScalef (1.0f / output->width (),
- -1.0f / output->height (),
- 1.0f);
- glTranslatef (-output->x1 (),
- -output->y2 (),
- 0.0f);
+ transform->translate (sAttrib->xTranslate,
+ sAttrib->yTranslate,
+ sAttrib->zTranslate + sAttrib->zCamera);
+ transform->rotate (sAttrib->xRotate, 0.0f, 1.0f, 0.0f);
+ transform->rotate (sAttrib->vRotate,
+ cosf (sAttrib->xRotate * DEG2RAD),
+ 0.0f,
+ sinf (sAttrib->xRotate * DEG2RAD));
+ transform->rotate (sAttrib->yRotate, 0.0f, 1.0f, 0.0f);
}
void
@@ -267,7 +232,7 @@ PrivateScreen::paintOutputRegion (const CompTransform *transform,
&offX, &offY);
vTransform = *transform;
- matrixTranslate (&vTransform, offX, offY, 0);
+ vTransform.translate (offX, offY, 0);
XOffsetRegion (w->clip (), -offX, -offY);
@@ -348,7 +313,7 @@ PrivateScreen::paintOutputRegion (const CompTransform *transform,
&offX, &offY);
vTransform = *transform;
- matrixTranslate (&vTransform, offX, offY, 0);
+ vTransform.translate (offX, offY, 0);
w->paint (&w->paintAttrib (), &vTransform, clip,
windowMask | PAINT_WINDOW_WITH_OFFSET_MASK);
}
@@ -386,7 +351,7 @@ CompScreen::enableOutputClipping (const CompTransform *transform,
GLdouble right[4] = { halfW / (cx - p2[0]), 0.0, 0.0, 0.5 };
glPushMatrix ();
- glLoadMatrixf (transform->m);
+ glLoadMatrixf (transform->getMatrix ());
glClipPlane (GL_CLIP_PLANE0, top);
glClipPlane (GL_CLIP_PLANE1, bottom);
@@ -438,11 +403,10 @@ CompScreen::paintTransformedOutput (const ScreenPaintAttrib *sAttrib,
{
enableOutputClipping (&sTransform, region, output);
- transformToScreenSpace (this, output, -sAttrib->zTranslate,
- &sTransform);
+ sTransform.toScreenSpace (output, -sAttrib->zTranslate);
glPushMatrix ();
- glLoadMatrixf (sTransform.m);
+ glLoadMatrixf (sTransform.getMatrix ());
priv->paintOutputRegion (&sTransform, region, output, mask);
@@ -452,11 +416,10 @@ CompScreen::paintTransformedOutput (const ScreenPaintAttrib *sAttrib,
}
else
{
- transformToScreenSpace (this, output, -sAttrib->zTranslate,
- &sTransform);
+ sTransform.toScreenSpace (output, -sAttrib->zTranslate);
glPushMatrix ();
- glLoadMatrixf (sTransform.m);
+ glLoadMatrixf (sTransform.getMatrix ());
priv->paintOutputRegion (&sTransform, region, output, mask);
@@ -506,10 +469,10 @@ CompScreen::paintOutput (const ScreenPaintAttrib *sAttrib,
setLighting (false);
- transformToScreenSpace (this, output, -DEFAULT_Z_CAMERA, &sTransform);
+ sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
glPushMatrix ();
- glLoadMatrixf (sTransform.m);
+ glLoadMatrixf (sTransform.getMatrix ());
priv->paintOutputRegion (&sTransform, region, output, mask);
@@ -1211,7 +1174,7 @@ CompWindow::paint (const WindowPaintAttrib *attrib,
mask & PAINT_WINDOW_WITH_OFFSET_MASK)
{
glPushMatrix ();
- glLoadMatrixf (transform->m);
+ glLoadMatrixf (transform->getMatrix ());
}
status = draw (transform, fragment, region, mask);
diff --git a/src/screen.cpp b/src/screen.cpp
index 7f9debf..163f797 100644
--- a/src/screen.cpp
+++ b/src/screen.cpp
@@ -4147,15 +4147,6 @@ CompScreen::waitForVideoSync ()
}
}
-static const CompTransform identity = {
- {
- 1.0, 0.0, 0.0, 0.0,
- 0.0, 1.0, 0.0, 0.0,
- 0.0, 0.0, 1.0, 0.0,
- 0.0, 0.0, 0.0, 1.0
- }
-};
-
void
CompScreen::paint (CompOutput::ptrList &outputs,
unsigned int mask)
@@ -4188,6 +4179,8 @@ CompScreen::paint (CompOutput::ptrList &outputs,
if (mask & COMP_SCREEN_DAMAGE_ALL_MASK)
{
+ CompMatrix identity;
+
paintOutput (&defaultScreenPaintAttrib,
&identity,
output->region (), output,
@@ -4196,6 +4189,8 @@ CompScreen::paint (CompOutput::ptrList &outputs,
}
else if (mask & COMP_SCREEN_DAMAGE_REGION_MASK)
{
+ CompMatrix identity;
+
XIntersectRegion (priv->display->mTmpRegion,
output->region (),
priv->display->mOutputRegion);
@@ -4205,6 +4200,8 @@ CompScreen::paint (CompOutput::ptrList &outputs,
priv->display->mOutputRegion, output,
PAINT_SCREEN_REGION_MASK))
{
+ identity.reset ();
+
paintOutput (&defaultScreenPaintAttrib,
&identity,
output->region (), output,
diff --git a/src/vector.cpp b/src/vector.cpp
new file mode 100644
index 0000000..e61a5ff
--- /dev/null
+++ b/src/vector.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * From Mesa 3-D graphics library.
+ */
+
+#include <string.h>
+#include <math.h>
+#include <compvector.h>
+
+CompVector::CompVector ()
+{
+ memset (v, 0, sizeof (v));
+}
+
+CompVector::CompVector (float x,
+ float y,
+ float z,
+ float w)
+{
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+ v[3] = w;
+}
+
+float&
+CompVector::operator[] (int item)
+{
+ return v[item];
+}
+
+float&
+CompVector::operator[] (VectorCoordsEnum coord)
+{
+ int item = (int) coord;
+ return v[item];
+}
+
+const float
+CompVector::operator[] (int item) const
+{
+ return v[item];
+}
+
+const float
+CompVector::operator[] (VectorCoordsEnum coord) const
+{
+ int item = (int) coord;
+ return v[item];
+}
+
+CompVector&
+CompVector::operator+= (const CompVector& rhs)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ v[i] += rhs[i];
+
+ return *this;
+}
+
+CompVector
+operator+ (const CompVector& lhs,
+ const CompVector& rhs)
+{
+ CompVector result;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ result[i] = lhs[i] + rhs[i];
+
+ return result;
+}
+
+CompVector&
+CompVector::operator-= (const CompVector& rhs)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ v[i] -= rhs[i];
+
+ return *this;
+}
+
+CompVector
+operator- (const CompVector& lhs,
+ const CompVector& rhs)
+{
+ CompVector result;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ result[i] = lhs[i] - rhs[i];
+
+ return result;
+}
+
+CompVector
+operator- (const CompVector& vector)
+{
+ CompVector result;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ result[i] = -vector[i];
+
+ return result;
+}
+
+CompVector&
+CompVector::operator*= (const float k)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ v[i] *= k;
+
+ return *this;
+}
+
+float
+operator* (const CompVector& lhs,
+ const CompVector& rhs)
+{
+ float result = 0;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ result += lhs[i] * rhs[i];
+
+ return result;
+}
+
+CompVector
+operator* (const float k,
+ const CompVector& vector)
+{
+ CompVector result;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ result[i] = k * vector[i];
+
+ return result;
+}
+
+CompVector
+operator* (const CompVector& vector,
+ const float k)
+{
+ return k * vector;
+}
+
+CompVector&
+CompVector::operator/= (const float k)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ v[i] /= k;
+
+ return *this;
+}
+
+CompVector
+operator/ (const CompVector& vector,
+ const float k)
+{
+ CompVector result;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ result[i] = vector[i] / k;
+
+ return result;
+}
+
+CompVector&
+CompVector::operator^= (const CompVector& vector)
+{
+ *this = *this ^ vector;
+ return *this;
+}
+
+CompVector
+operator^ (const CompVector& lhs,
+ const CompVector& rhs)
+{
+ CompVector result;
+
+ result[0] = lhs[1] * rhs[2] - lhs[2] * rhs[1];
+ result[1] = lhs[2] * rhs[0] - lhs[0] * rhs[2];
+ result[2] = lhs[0] * rhs[1] - lhs[1] * rhs[0];
+ result[3] = 0.0f;
+
+ return result;
+}