[svn:parrot] r39693 - in trunk: config/gen/makefiles examples/opengl runtime/parrot/library/OpenGL
japhb at svn.parrot.org
japhb at svn.parrot.org
Mon Jun 22 02:23:30 UTC 2009
Author: japhb
Date: Mon Jun 22 02:23:28 2009
New Revision: 39693
URL: https://trac.parrot.org/parrot/changeset/39693
Log:
[OpenGL] Beginnings of OpenGL::Math (not yet generally usable)
Added:
trunk/examples/opengl/math.pir
trunk/runtime/parrot/library/OpenGL/
trunk/runtime/parrot/library/OpenGL/Math.pir
Modified:
trunk/config/gen/makefiles/root.in
Modified: trunk/config/gen/makefiles/root.in
==============================================================================
--- trunk/config/gen/makefiles/root.in Sun Jun 21 22:08:28 2009 (r39692)
+++ trunk/config/gen/makefiles/root.in Mon Jun 22 02:23:28 2009 (r39693)
@@ -262,6 +262,7 @@
$(LIBRARY_DIR)/ncurses.pbc \
#IF(has_opengl): $(LIBRARY_DIR)/OpenGL.pbc \
#IF(has_opengl): $(LIBRARY_DIR)/OpenGL_funcs.pbc \
+#IF(has_opengl): $(LIBRARY_DIR)/OpenGL/Math.pbc \
$(LIBRARY_DIR)/P6object.pbc \
$(LIBRARY_DIR)/parrotlib.pbc \
$(LIBRARY_DIR)/pcore.pbc \
Added: trunk/examples/opengl/math.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/examples/opengl/math.pir Mon Jun 22 02:23:28 2009 (r39693)
@@ -0,0 +1,63 @@
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 TITLE
+
+math.pir - Demo OpenGL::Math module
+
+=head1 SYNOPSIS
+
+ $ cd parrot-home
+ $ ./parrot examples/opengl/math.pir
+
+=head1 DESCRIPTION
+
+NOTE: THIS IS JUST A STUB WHILE OpenGL::Math IS BEING DEVELOPED. IT WILL BE
+ FILLED OUT LATER.
+
+This is a simple demo of functionality available from the C<OpenGL::Math>
+Parrot module.
+
+=cut
+
+.sub main :main
+ # Load OpenGL::Math and data dumping debug module
+ load_bytecode 'OpenGL/Math.pbc'
+ load_bytecode 'dumper.pbc'
+
+ # Test some basics
+ $P1 = new 'FixedFloatArray'
+ $P1 = 4
+ $P1[0] = 0.5
+ $P1[1] = 1.0
+ $P1[2] = 2.0
+ $P1[3] = 4.0
+
+ $P2 = new 'FixedFloatArray'
+ $P2 = 4
+ $P2[0] = 1.0
+ $P2[1] = 2.0
+ $P2[2] = 3.0
+ $P2[3] = 4.0
+
+ .local pmc Vec4
+ Vec4 = get_class ['OpenGL';'Math';'Vec4']
+
+ $P3 = new Vec4
+ $P3.'set_vals'($P1)
+
+ $P4 = new Vec4
+ $P4.'set_vals'($P2)
+
+ $P5 = $P3.'mult'($P4)
+
+ _dumper($P3, 'Vec4')
+ _dumper($P4, 'Vec4')
+ _dumper($P5, 'Vec4')
+.end
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
Added: trunk/runtime/parrot/library/OpenGL/Math.pir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/runtime/parrot/library/OpenGL/Math.pir Mon Jun 22 02:23:28 2009 (r39693)
@@ -0,0 +1,629 @@
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+OpenGL;Math - Parrot extension for linear algebra following OpenGL conventions
+
+=head1 SYNOPSIS
+
+For more examples, look in F<examples/opengl/>, starting with
+F<examples/opengl/math.pir>.
+
+ # During init ...
+ load_bytecode 'OpenGL/Math.pbc'
+
+ # Later ...
+ XXX - NEED CODE HERE
+
+=head1 DESCRIPTION
+
+NOTE: THIS IS A WORK IN PROGRESS, AND SHOULD NOT BE CONSIDERED USABLE YET.
+
+Any 3D API has to pick certain conventions for handling of vectors and
+matrices, such as the handedness of the default coordinate systems,
+whether matrices are packed in column-major or row-major order, and
+so forth.
+
+This module implements the basic operations of linear algebra according
+to the conventions chosen by OpenGL, and attempts to do so efficiently
+within the bounds set by a pure PIR implementation. It also provides
+efficient packing and unpacking of matrix and vector elements so that
+users need not directly understand the vagaries of OpenGL NCI structures.
+
+Finally, it is a primary goal that users of this module should not need to
+provide any hand-written versions of standard OpenGL matrix manipulations.
+Thus, methods are provided to perform rotations, translations, projections,
+etc.
+
+=cut
+
+.namespace ['OpenGL';'Math']
+
+=head2 OpenGL;Math
+
+The OpenGL;Math class/namespace handles the necessary housekeeping to make
+everything else work smoothly.
+
+=head3 Initialization
+
+The initialization routines are mostly for internal use only. They
+include:
+
+=over 4
+
+=cut
+
+=item _opengl_math_init()
+
+At module load time, calls the other initialization routines in the proper
+order.
+
+=cut
+
+.sub _opengl_math_init :load
+ _create_classes()
+.end
+
+=item _create_classes()
+
+Creates Parrot classes to match each of the OpenGL;Math namespaces, and
+sets up their attributes.
+
+=cut
+
+.sub _create_classes
+ .local pmc Vec4
+ Vec4 = newclass ['OpenGL';'Math';'Vec4']
+ addattribute Vec4, 'vals'
+.end
+
+=back
+
+=cut
+
+
+.namespace ['OpenGL';'Math';'Vec4']
+
+=head2 OpenGL;Math;Vec4
+
+=head3 Instantiation
+
+=over 4
+
+=item Vec4 vec4 = new Vec4
+
+Create a new object representing a four-element vector. You will need
+to set the initial values using the C<set_vals()> method.
+
+=back
+
+
+=head3 Accessors
+
+=over 4
+
+=item pmc vals = vector.get_vals()
+
+Return a four element array representing the current vector value.
+
+=cut
+
+.sub get_vals :method
+ $P0 = getattribute self, 'vals'
+ .return($P0)
+.end
+
+=item vector.set_vals(pmc vals)
+
+Set the current vector value to a four element array.
+
+=cut
+.sub set_vals :method
+ .param pmc vals
+
+ $I0 = vals
+ unless $I0 == 4 goto wrong_vector_length
+
+ setattribute self, 'vals', vals
+ .return()
+
+ wrong_vector_length:
+ $S0 = 'Input vector is wrong length ('
+ $S1 = $I0
+ $S0 .= $S1
+ $S0 .= ')'
+ die $S0
+.end
+
+=back
+
+
+=head3 Elementwise Operations
+
+=over 4
+
+=item Vec4 result = vec1.add(Vec4 vec2)
+
+Calculate the elementwise addition C<vec1 + vec2> and return
+a new C<Vec4> vector C<result>.
+
+=cut
+
+.sub add :method
+ .param pmc vec2
+
+ .local pmc v1, v2
+ v1 = getattribute self, 'vals'
+ v2 = getattribute vec2, 'vals'
+
+ .local pmc v3
+ v3 = new 'FixedFloatArray'
+ v3 = 4
+
+ $N10 = v1[0]
+ $N11 = v1[1]
+ $N12 = v1[2]
+ $N13 = v1[3]
+
+ $N20 = v2[0]
+ $N21 = v2[1]
+ $N22 = v2[2]
+ $N23 = v2[3]
+
+ $N30 = $N10 + $N20
+ $N31 = $N11 + $N21
+ $N32 = $N12 + $N22
+ $N33 = $N13 + $N23
+
+ v3[0] = $N30
+ v3[1] = $N31
+ v3[2] = $N32
+ v3[3] = $N33
+
+ .local pmc result
+ $P0 = typeof self
+ result = new $P0
+ setattribute result, 'vals', v3
+
+ .return(result)
+.end
+
+
+=item Vec4 result = vec1.sub(Vec4 vec2)
+
+Calculate the elementwise subtraction C<vec1 - vec2> and return
+a new C<Vec4> vector C<result>.
+
+=cut
+
+.sub sub :method
+ .param pmc vec2
+
+ .local pmc v1, v2
+ v1 = getattribute self, 'vals'
+ v2 = getattribute vec2, 'vals'
+
+ .local pmc v3
+ v3 = new 'FixedFloatArray'
+ v3 = 4
+
+ $N10 = v1[0]
+ $N11 = v1[1]
+ $N12 = v1[2]
+ $N13 = v1[3]
+
+ $N20 = v2[0]
+ $N21 = v2[1]
+ $N22 = v2[2]
+ $N23 = v2[3]
+
+ $N30 = $N10 - $N20
+ $N31 = $N11 - $N21
+ $N32 = $N12 - $N22
+ $N33 = $N13 - $N23
+
+ v3[0] = $N30
+ v3[1] = $N31
+ v3[2] = $N32
+ v3[3] = $N33
+
+ .local pmc result
+ $P0 = typeof self
+ result = new $P0
+ setattribute result, 'vals', v3
+
+ .return(result)
+.end
+
+
+=item Vec4 result = vec1.mult(Vec4 vec2)
+
+Calculate the elementwise multiplication C<vec1 * vec2> and return
+a new C<Vec4> vector C<result>.
+
+=cut
+
+.sub mult :method
+ .param pmc vec2
+
+ .local pmc v1, v2
+ v1 = getattribute self, 'vals'
+ v2 = getattribute vec2, 'vals'
+
+ .local pmc v3
+ v3 = new 'FixedFloatArray'
+ v3 = 4
+
+ $N10 = v1[0]
+ $N11 = v1[1]
+ $N12 = v1[2]
+ $N13 = v1[3]
+
+ $N20 = v2[0]
+ $N21 = v2[1]
+ $N22 = v2[2]
+ $N23 = v2[3]
+
+ $N30 = $N10 * $N20
+ $N31 = $N11 * $N21
+ $N32 = $N12 * $N22
+ $N33 = $N13 * $N23
+
+ v3[0] = $N30
+ v3[1] = $N31
+ v3[2] = $N32
+ v3[3] = $N33
+
+ .local pmc result
+ $P0 = typeof self
+ result = new $P0
+ setattribute result, 'vals', v3
+
+ .return(result)
+.end
+
+
+=item Vec4 result = vec1.div(Vec4 vec2)
+
+Calculate the elementwise division C<vec1 / vec2> and return a new C<Vec4>
+vector C<result>. No attempt is made to prevent division by zero,
+XXX - SO WHAT HAPPENS?
+
+=cut
+
+.sub div :method
+ .param pmc vec2
+
+ .local pmc v1, v2
+ v1 = getattribute self, 'vals'
+ v2 = getattribute vec2, 'vals'
+
+ .local pmc v3
+ v3 = new 'FixedFloatArray'
+ v3 = 4
+
+ $N10 = v1[0]
+ $N11 = v1[1]
+ $N12 = v1[2]
+ $N13 = v1[3]
+
+ $N20 = v2[0]
+ $N21 = v2[1]
+ $N22 = v2[2]
+ $N23 = v2[3]
+
+ $N30 = $N10 / $N20
+ $N31 = $N11 / $N21
+ $N32 = $N12 / $N22
+ $N33 = $N13 / $N23
+
+ v3[0] = $N30
+ v3[1] = $N31
+ v3[2] = $N32
+ v3[3] = $N33
+
+ .local pmc result
+ $P0 = typeof self
+ result = new $P0
+ setattribute result, 'vals', v3
+
+ .return(result)
+.end
+
+
+=item Vec4 result = vec1.mod(Vec4 vec2)
+
+Calculate the elementwise modulus C<vec1 % vec2> and return
+a new C<Vec4> vector C<result>.
+
+=cut
+
+.sub mod :method
+ .param pmc vec2
+
+ .local pmc v1, v2
+ v1 = getattribute self, 'vals'
+ v2 = getattribute vec2, 'vals'
+
+ .local pmc v3
+ v3 = new 'FixedFloatArray'
+ v3 = 4
+
+ $N10 = v1[0]
+ $N11 = v1[1]
+ $N12 = v1[2]
+ $N13 = v1[3]
+
+ $N20 = v2[0]
+ $N21 = v2[1]
+ $N22 = v2[2]
+ $N23 = v2[3]
+
+ $N30 = $N10 % $N20
+ $N31 = $N11 % $N21
+ $N32 = $N12 % $N22
+ $N33 = $N13 % $N23
+
+ v3[0] = $N30
+ v3[1] = $N31
+ v3[2] = $N32
+ v3[3] = $N33
+
+ .local pmc result
+ $P0 = typeof self
+ result = new $P0
+ setattribute result, 'vals', v3
+
+ .return(result)
+.end
+
+
+=back
+
+
+=head3 Other Operations
+
+=over 4
+
+=item Vec4 cp = vec1.cross(Vec4 vec2)
+
+Calculate the cross product C<vec1 cross vec2> (using only the first three
+elements of each vector), and return the result as a new C<Vec4> whose
+first three elements are the cross product and whose last element is 1.0.
+
+=cut
+
+.sub cross :method
+ .param pmc vec2
+
+ .local pmc v1, v2
+ v1 = getattribute self, 'vals'
+ v2 = getattribute vec2, 'vals'
+
+ .local pmc v3
+ v3 = new 'FixedFloatArray'
+ v3 = 4
+
+ $N10 = v1[0]
+ $N11 = v1[1]
+ $N12 = v1[2]
+
+ $N20 = v2[0]
+ $N21 = v2[1]
+ $N22 = v2[2]
+
+ $N0 = $N11 * $N22
+ $N1 = $N21 * $N12
+ $N30 = $N0 - $N1
+
+ $N2 = $N20 * $N12
+ $N3 = $N10 * $N22
+ $N31 = $N2 - $N3
+
+ $N4 = $N10 * $N21
+ $N5 = $N20 * $N11
+ $N32 = $N4 - $N5
+
+ v3[0] = $N30
+ v3[1] = $N31
+ v3[2] = $N32
+ v3[3] = 1.0
+
+ .local pmc result
+ $P0 = typeof self
+ result = new $P0
+ setattribute result, 'vals', v3
+
+ .return(result)
+.end
+
+
+=item num dp = vec1.dot(Vec4 vec2)
+
+Calculate the dot product C<vec1 dot vec2> and return the result as a num.
+
+=cut
+
+.sub dot :method
+ .param pmc vec2
+
+ .local pmc v1, v2
+ v1 = getattribute self, 'vals'
+ v2 = getattribute vec2, 'vals'
+
+ $N10 = v1[0]
+ $N11 = v1[1]
+ $N12 = v1[2]
+ $N13 = v1[3]
+
+ $N20 = v2[0]
+ $N21 = v2[1]
+ $N22 = v2[2]
+ $N23 = v2[3]
+
+ $N30 = $N10 * $N20
+ $N31 = $N11 * $N21
+ $N32 = $N12 * $N22
+ $N33 = $N13 * $N23
+
+ .local num result
+
+ result = $N30 + $N31
+ result += $N32
+ result += $N33
+
+ .return(result)
+.end
+
+
+=item num dp3 = vec1.dot3(Vec4 vec2)
+
+Calculate the dot product C<vec1 dot vec2>, considering only the first
+three elements of each vector, and return the result as a num.
+
+=cut
+
+.sub dot3 :method
+ .param pmc vec2
+
+ .local pmc v1, v2
+ v1 = getattribute self, 'vals'
+ v2 = getattribute vec2, 'vals'
+
+ $N10 = v1[0]
+ $N11 = v1[1]
+ $N12 = v1[2]
+
+ $N20 = v2[0]
+ $N21 = v2[1]
+ $N22 = v2[2]
+
+ $N30 = $N10 * $N20
+ $N31 = $N11 * $N21
+ $N32 = $N12 * $N22
+
+ .local num result
+
+ result = $N30 + $N31
+ result += $N32
+
+ .return(result)
+.end
+
+
+=item num len = vector.length()
+
+Calculate the length of C<vector> as C<sqrt(vector dot vector)>, and return
+the result as a num.
+
+=cut
+
+.sub length :method
+ $N0 = self.'dot'(self)
+ $N1 = sqrt $N0
+
+ .return($N1)
+.end
+
+
+=item num len3 = vector.length3()
+
+Calculate the length of C<vector> as C<sqrt(vector dot3 vector)> (thus
+considering only the first three elements), and return the result as a num.
+
+=cut
+
+.sub length :method
+ $N0 = self.'dot3'(self)
+ $N1 = sqrt $N0
+
+ .return($N1)
+.end
+
+
+=item num dist = vec1.distance(vec2)
+
+Treat two vectors C<vec1> and C<vec2> as points and determine the distance
+between them as C<length(vec1 - vec2)>, returning the result as a num.
+
+=cut
+
+.sub distance :method
+ .param pmc vec2
+
+ $P0 = self.'sub'(vec2)
+ $N0 = $P0.'length'()
+
+ .return($N0)
+.end
+
+
+=item num dist3 = vec1.distance3(vec2)
+
+Treat two vectors C<vec1> and C<vec2> as points and determine the distance
+between them as C<length3(vec1 - vec2)> (thus considering only the first
+three elements), and returning the result as a num.
+
+=cut
+
+.sub distance3 :method
+ .param pmc vec2
+
+ $P0 = self.'sub'(vec2)
+ $N0 = $P0.'length3'()
+
+ .return($N0)
+.end
+
+=back
+
+
+
+=head3 Miscellaneous Methods
+
+=over 4
+
+=item __dump(pmc dumper, str label)
+
+Callback function for Parrot's C<Data::Dumper> clone.
+
+=cut
+
+.sub __dump :method
+ .param pmc dumper
+ .param string label
+
+ ($S1, $S0) = dumper.'newIndent'()
+ say '['
+ print $S1
+ print 'vals = '
+ $P0 = getattribute self, 'vals'
+ dumper.'genericArray'('vals', $P0)
+ say ''
+ print $S0
+ say ']'
+.end
+
+=back
+
+
+=head1 ROADMAP
+
+Over time, the API provided by this module will grow to incorporate
+related low-level operations, such as quaternion ops. However, it will
+B<not> include high level components such as particle systems and physics
+simulations. These are properly the domain of other modules that use
+this one, or NCI wrappers for libraries such as ODE (L<http://www.ode.org/>)
+and Bullet (L<http://www.bulletphysics.com/wordpress/>).
+
+In order to allow the greatest audience of users, this module will track
+the evolving experimental API for HLL access to PIR modules.
+
+=cut
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
More information about the parrot-commits
mailing list