package require tcl3d

proc CompareMatf { m1 m2 } {
    if { ! [tcl3dMatfCompare $m1 $m2 1.0E-5] } {
        puts "Tcl3D Matrix:"
        tcl3dMatPrint $m1 "%10.7f"
        puts "OpenGL Matrix:"
        tcl3dMatPrint $m2 "%10.7f"
        error "Matrices are not identical"
    }
}

proc CompareMatd { m1 m2 } {
    if { ! [tcl3dMatdCompare $m1 $m2 1.0E-6] } {
        puts "Tcl3D Matrix:"
        tcl3dMatPrint $m1 "%10.7f"
        puts "OpenGL Matrix:"
        tcl3dMatPrint $m2 "%10.7f"
        error "Matrices are not identical"
    }
}

togl .t
glMatrixMode GL_MODELVIEW

set v     [tcl3dVector GLfloat 16]
set vgl   [tcl3dVector GLfloat 16]
set tfm   [tcl3dVector GLfloat 16]
set tv    [tcl3dVectorFromArgs GLfloat 1 2 3]
set p     [tcl3dVectorFromArgs GLfloat 1 2 3]
set resp  [tcl3dVectorFromArgs GLfloat 10 10 10]
set axis1 [tcl3dVectorFromArgs GLfloat 1 1 1]
set axis2 [tcl3dVectorFromArgs GLfloat 0.3 -0.8 1.6]

set dv     [tcl3dVector GLdouble 16]
set dvgl   [tcl3dVector GLdouble 16]
set dtfm   [tcl3dVector GLdouble 16]
set dtv    [tcl3dVectorFromArgs GLdouble 1 2 3]
set dp     [tcl3dVectorFromArgs GLdouble 1 2 3]
set dresp  [tcl3dVectorFromArgs GLdouble 10 10 10]
set daxis1 [tcl3dVectorFromArgs GLdouble 1 1 1]
set daxis2 [tcl3dVectorFromArgs GLdouble 0.3 -0.8 1.6]

puts "New single matrix:"
set mi   [tcl3dVector GLfloat 16]
set migl [tcl3dVector GLfloat 16]
CompareMatf $mi $migl
tcl3dMatPrint $mi
puts "New double matrix:"
set dmi   [tcl3dVector GLdouble 16]
set dmigl [tcl3dVector GLdouble 16]
CompareMatd $dmi $dmigl
tcl3dMatPrint $dmi
puts ""

puts "Identity single matrix:"
tcl3dMatfIdentity $mi
glLoadIdentity
glGetFloatv GL_MODELVIEW_MATRIX $migl
CompareMatf $mi $migl
tcl3dMatPrint $mi
puts "Identity double matrix:"
tcl3dMatdIdentity $dmi
glLoadIdentity
glGetDoublev GL_MODELVIEW_MATRIX $dmigl
CompareMatd $dmi $dmigl
tcl3dMatPrint $dmi
puts ""

puts "Copied identity single matrix:"
tcl3dMatfCopy $mi $v
glPushMatrix
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Copied identity double matrix:"
tcl3dMatdCopy $dmi $dv
glPushMatrix
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Translation single matrix (created with tcl3dMatfTranslate):"
tcl3dMatfTranslate 1 2 3 $v
glLoadIdentity
glTranslatef 1 2 3
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Translation double matrix (created with tcl3dMatdTranslate):"
tcl3dMatdTranslate 1 2 3 $dv
glLoadIdentity
glTranslated 1 2 3
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Translation single matrix (created with tcl3dMatfTranslatev):"
tcl3dMatfCopy $mi $v
tcl3dMatfTranslatev $tv $v
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Translation double matrix (created with tcl3dMatdTranslatev):"
tcl3dMatdCopy $dmi $dv
tcl3dMatdTranslatev $dtv $dv
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Rotation single matrix (90 degrees around X):"
tcl3dMatfCopy $mi $v
tcl3dMatfRotateX 90 $v
glLoadIdentity
glRotatef 90  1 0 0
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Rotation double matrix (90 degrees around X):"
tcl3dMatdCopy $dmi $dv
tcl3dMatdRotateX 90 $dv
glLoadIdentity
glRotated 90  1 0 0
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Rotation single matrix (90 degrees around Y):"
tcl3dMatfCopy $mi $v
tcl3dMatfRotateY 90 $v
glLoadIdentity
glRotatef 90  0 1 0
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Rotation double matrix (90 degrees around Y):"
tcl3dMatdCopy $dmi $dv
tcl3dMatdRotateY 90 $dv
glLoadIdentity
glRotated 90  0 1 0
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Rotation single matrix (90 degrees around Z):"
tcl3dMatfCopy $mi $v
tcl3dMatfRotateZ 90 $v
glLoadIdentity
glRotatef 90  0 0 1
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Rotation double matrix (90 degrees around Z):"
tcl3dMatdCopy $dmi $dv
tcl3dMatdRotateZ 90 $dv
glLoadIdentity
glRotated 90  0 0 1
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Rotation single matrix (90 degrees around axis (1,1,1)):"
tcl3dMatfCopy $mi $v
tcl3dMatfRotate 90 $axis1 $v
glLoadIdentity
glRotatef 90  1 1 1
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Rotation double matrix (90 degrees around axis (1,1,1)):"
tcl3dMatdCopy $dmi $dv
tcl3dMatdRotate 90 $daxis1 $dv
glLoadIdentity
glRotated 90  1 1 1
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Rotation single matrix (32.2 degrees around axis (0.3,-0.8,1.6)):"
tcl3dMatfCopy $mi $v
tcl3dMatfRotate 32.2 $axis2 $v
glLoadIdentity
glRotatef 32.2  0.3 -0.8 1.6
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Rotation double matrix (32.2 degrees around axis (0.3,-0.8,1.6)):"
tcl3dMatdCopy $dmi $dv
tcl3dMatdRotate 32.2 $daxis2 $dv
glLoadIdentity
glRotated 32.2  0.3 -0.8 1.6
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Scale single matrix (created with tcl3dMatfScale):"
tcl3dMatfCopy $mi $v
tcl3dMatfScale 1 2 3 $v
glLoadIdentity
glScalef 1 2 3
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Scale double matrix (created with tcl3dMatdScale):"
tcl3dMatdCopy $dmi $dv
tcl3dMatdScale 1 2 3 $dv
glLoadIdentity
glScaled 1 2 3
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Scale single matrix (created with tcl3dMatfScalev):"
tcl3dMatfCopy $mi $v
tcl3dMatfScalev $tv $v
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Scale double matrix (created with tcl3dMatdScalev):"
tcl3dMatdCopy $dmi $dv
tcl3dMatdScalev $dtv $dv
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Translation single matrix applied to point (1,2,3)):"
tcl3dMatfCopy $mi $tfm
tcl3dMatfTranslate 3 2 1 $tfm
tcl3dMatfTransformPoint $p $tfm $resp
tcl3dMatPrint $tfm
puts -nonewline "Transformed point: "
tcl3dVec3Print $resp
puts "Translation double matrix applied to point (1,2,3)):"
tcl3dMatdCopy $dmi $dtfm
tcl3dMatdTranslate 3 2 1 $dtfm
tcl3dMatdTransformPoint $dp $dtfm $dresp
tcl3dMatPrint $dtfm
puts -nonewline "Transformed point: "
tcl3dVec3Print $dresp
puts ""

puts "Translation single matrix applied to vector (1,2,3)):"
tcl3dMatfCopy $mi $tfm
tcl3dMatfTranslate 3 2 1 $tfm
tcl3dMatfTransformVector $p $tfm $resp
tcl3dMatPrint $tfm
puts -nonewline "Transformed vector: "
tcl3dVec3Print $resp
puts "Translation double matrix applied to vector (1,2,3)):"
tcl3dMatdCopy $dmi $dtfm
tcl3dMatdTranslate 3 2 1 $dtfm
tcl3dMatdTransformVector $dp $dtfm $dresp
tcl3dMatPrint $dtfm
puts -nonewline "Transformed vector: "
tcl3dVec3Print $dresp
puts ""

puts "Combined matrix (using tcl3dTranslatef, tcl3dRotatef, tcl3dScalef):"
# Sequence with Tcl3D replacement functions.
tcl3dMatfIdentity $v
tcl3dRotatef 32.2  0.3 -0.8 1.6 $v
tcl3dScalef 3 2 1 $v
tcl3dTranslatef 1.1 2.1 3.1 $v
tcl3dRotatef 76.5  3.3 9.8 -10.6 $v
# Sequence with OpenGL functions.
glLoadIdentity
glRotatef 32.2  0.3 -0.8 1.6
glScalef 3 2 1
glTranslatef 1.1 2.1 3.1
glRotatef 76.5  3.3 9.8 -10.6
# Get OpenGL matrix and compare with Tcl3D matrix.
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Combined matrix (using tcl3dTranslated, tcl3dRotated, tcl3dScaled):"
# Sequence with Tcl3D replacement functions.
tcl3dMatdIdentity $dv
tcl3dRotated 32.2  0.3 -0.8 1.6 $dv
tcl3dScaled 3 2 1 $dv
tcl3dTranslated 1.1 2.1 3.1 $dv
tcl3dRotated 76.5  3.3 9.8 -10.6 $dv
# Sequence with OpenGL functions.
glLoadIdentity
glRotated 32.2  0.3 -0.8 1.6
glScaled 3 2 1
glTranslated 1.1 2.1 3.1
glRotated 76.5  3.3 9.8 -10.6
# Get OpenGL matrix and compare with Tcl3D matrix.
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Combined matrix (using tcl3dMultMatrixf):"
# Sequence with Tcl3D replacement functions.
tcl3dMatfIdentity $tfm
tcl3dRotatef 32.2  0.3 -0.8 1.6 $tfm
tcl3dTranslatef 1.1 2.1 3.1 $tfm
tcl3dMatfCopy $tfm $v
tcl3dMatfIdentity $tfm
tcl3dRotatef 76.5  3.3 9.8 -10.6 $tfm
tcl3dMultMatrixf $tfm $v
# Sequence with OpenGL functions.
tcl3dMatfIdentity $tfm
tcl3dRotatef 32.2  0.3 -0.8 1.6 $tfm
tcl3dTranslatef 1.1 2.1 3.1 $tfm
glLoadMatrixf [tcl3dVectorToList $tfm 16]
tcl3dMatfIdentity $tfm
tcl3dRotatef 76.5  3.3 9.8 -10.6 $tfm
glMultMatrixf [tcl3dVectorToList $tfm 16]
# Get OpenGL matrix and compare with Tcl3D matrix.
glGetFloatv GL_MODELVIEW_MATRIX $vgl
CompareMatf $v $vgl
tcl3dMatPrint $v
puts "Combined matrix (using tcl3dMultMatrixd):"
# Sequence with Tcl3D replacement functions.
tcl3dMatdIdentity $dtfm
tcl3dRotated 32.2  0.3 -0.8 1.6 $dtfm
tcl3dTranslated 1.1 2.1 3.1 $dtfm
tcl3dMatdCopy $dtfm $dv
tcl3dMatdIdentity $dtfm
tcl3dRotated 76.5  3.3 9.8 -10.6 $dtfm
tcl3dMultMatrixd $dtfm $dv
# Sequence with OpenGL functions.
tcl3dMatdIdentity $dtfm
tcl3dRotated 32.2  0.3 -0.8 1.6 $dtfm
tcl3dTranslated 1.1 2.1 3.1 $dtfm
glLoadMatrixd [tcl3dVectorToList $dtfm 16]
tcl3dMatdIdentity $dtfm
tcl3dRotated 76.5  3.3 9.8 -10.6 $dtfm
glMultMatrixd [tcl3dVectorToList $dtfm 16]
# Get OpenGL matrix and compare with Tcl3D matrix.
glGetDoublev GL_MODELVIEW_MATRIX $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dv
puts ""

puts "Copy single matrix to double matrix:"
tcl3dMatf2Matd $v $dvgl
CompareMatd $dv $dvgl
tcl3dMatPrint $dvgl
puts "Copy double matrix to single matrix:"
tcl3dMatd2Matf $dv $vgl
CompareMatf $v $vgl
tcl3dMatPrint $vgl

exit
