# OSG BoundingVolumes (BV) specific test procedures.
# OSG currently supports BoundingBox and BoundingSphere classes.
# These procedures are independent of the supplied BV class type.
#
# Cnstr-BBox      BBox constructors.        BBox as result.
# BBox-Scalar     BBox as input.            Scalar as result.
# BBoxBBox-Scalar BBox and BBox as input.   Scalar as result.
# BBoxBBox-BBox   BBox and BBox as input.   BBox as result.
# BBox-Vec        BBox as input.            Vector as result.
# BBoxMisc        Miscellaneous BBox tests: set, expandBy, ...

package require tcl3d

source testUtil.tcl

# Test procedure for the different types of BoundingBox constructors.
proc Cnstr-BBox { bvType } {
    P "\nCnstr-BBox: $bvType Functionality: set BBox \[$bvType\]"

    set bv1 [osg::BoundingBox]
    PN "Cnstr()" ; PBB $bv1 "%g"

    set bv2 [osg::BoundingBox -args 1 2 3  4 5 6]
    PN "Cnstr(1 2 ...)" ; PBB $bv2

    set bv3 [osg::BoundingBox -args [osg::Vec3 -args 1 2 3] [osg::Vec3 -args 4 5 6]]
    PN "Cnstr(Vec3, Vec3)" ; PBB $bv3
}

# Test procedure for methods returning scalar information about a BoundingBox
# without the need to supply parameters.
proc BBox-Scalar { bvType bv } {
    P "\nBBox-Scalar: $bvType Functionality: set Scalar \[\$In method\]"
    PN "In $bvType" ; PBB $bv
    foreach m { valid xMin yMin zMin xMax yMax zMax radius radius2 } {
        set retVal [catch {eval $bv $m} result]
        PN "Method $m"
        if { $retVal == 0 } {
            P $result
        } else {
            P "Not supported ($result)"
        }
    }
}

# Test procedure for methods returning a scalar generated
# by supplying two BoundingBoxes.
proc BBoxBBox-Scalar { bvType bv1 bv2 } {
    P "\nBBoxBBox-Scalar: $bvType Functionality: set Scalar \[\$In1 method \$In2\]"
    PN "In1 $bvType" ; PBB $bv1
    PN "In2 $bvType" ; PBB $bv2
    foreach m { intersects } {
        set retVal [catch {eval $bv1 $m $bv2} result]
        PN "Method $m"
        if { $retVal == 0 } {
            P $result
        } else {
            P "Not supported ($result)"
        }
    }
    return $result
}

# Test procedure for methods returning a BoundingBox generated
# by supplying two BoundingBoxes.
proc BBoxBBox-BBox { bvType bv1 bv2 } {
    P "\nBBoxBBox-BBox: $bvType Functionality: set BBox \[\$In1 method \$In2\]"
    PN "In1 $bvType" ; PBB $bv1
    PN "In2 $bvType" ; PBB $bv2
    foreach m { intersect } {
        set retVal [catch {eval $bv1 $m $bv2} result]
        PN "Method $m"
        if { $retVal == 0 } {
            PBB $result
        } else {
            P "Not supported ($result)"
        }
    }
    return $result
}

# Test procedure for methods returning a vector generated from
# a supplied BoundingBox.
proc BBox-Vec { bvType bv } {
    P "\nBBox-Vec: $bvType Functionality: set Vector \[\$In method\]"
    PN "In $bvType" ; PBB $bv
    foreach m { center } {
        set retVal [catch {eval $bv $m} result]
        PN "Method $m"
        if { $retVal == 0 } {
            PV "$result"
        } else {
            P "Not supported ($result)"
        }
    }
    return $result
}

# Test procedure for methods not fitting into one of the above categories.
proc BBoxMisc { bvType } {
    P "\nBBoxMisc: $bvType Functionality: Miscellaneous"

    set bv1 [CreateBBox1]
    $bv1 init
    PN "Method init:" ; PBB $bv1 "%g"

    $bv1 set  1 2 3  4 5 6
    PN "Method set 1 2 ..:" ; PBB $bv1

    $bv1 set [CreateUnitVec osg::Vec3 3 1] [CreateVec1 osg::Vec3 3]
    PN "Method set Vec3,Vec3:" ; PBB $bv1

    for { set i 0 } { $i < 8 } { incr i } {
        set corner [$bv1 corner $i]
        PN "Method corner $i:" ; PV $corner
    }

    $bv1 expandBy [osg::Vec3 -args 0 4 0]
    PN "Method expandBy Vec3:" ; PBB $bv1

    $bv1 expandBy 4 0 0
    PN "Method expandBy x,y,z:" ; PBB $bv1

    $bv1 expandBy [CreateBBox1]
    PN "Method expandBy BBox:" ; PBB $bv1

    $bv1 expandBy [CreateBSphere1]
    PN "Method expandBy BSphere:" ; PBB $bv1

    set retVal [$bv1 contains [osg::Vec3 -args 0 1 2]]
    PN "Method contains Vec3:" ; P $retVal
}

# Test procedure for the different types of BoundingSphere constructors.
proc Cnstr-BSphere { bvType } {
    P "\nCnstr-BSphere: $bvType Functionality: set BSphere \[$bvType\]"

    set bv1 [osg::BoundingSphere]
    PN "Cnstr():" ; PBS $bv1

    set bv2 [osg::BoundingSphere -args [osg::Vec3] 4]
    PN "Cnstr(Vec3,r):" ; PBS $bv2

    set bv3 [osg::BoundingSphere -args $bv2]
    PN "Cnstr(BSphere):" ; PBS $bv3

    set bv4 [osg::BoundingSphere -args [CreateBBox1]]
    PN "Cnstr(BBox):" ; PBS $bv4
}

# Test procedure for methods returning scalar information about a BoundingSphere
# without the need to supply parameters.
proc BSphere-Scalar { bvType bv } {
    P "\nBSphere-Scalar: $bvType Functionality: set Scalar \[\$In method\]"
    PN "In $bvType" ; PBS $bv
    foreach m { valid radius radius2 } {
        set retVal [catch {eval $bv $m} result]
        PN "Method $m"
        if { $retVal == 0 } {
            P $result
        } else {
            P "Not supported ($result)"
        }
    }
}

# Test procedure for methods returning a scalar generated
# by supplying two BoundingSpherees.
proc BSphereBSphere-Scalar { bvType bv1 bv2 } {
    P "\nBSphereBSphere-Scalar: $bvType Functionality: set Scalar \[\$In1 method \$In2\]"
    PN "In1 $bvType" ; PBS $bv1
    PN "In2 $bvType" ; PBS $bv2
    foreach m { intersects } {
        set retVal [catch {eval $bv1 $m $bv2} result]
        PN "Method $m"
        if { $retVal == 0 } {
            P $result
        } else {
            P "Not supported ($result)"
        }
    }
    return $result
}

# Test procedure for methods returning a vector generated from
# a supplied BoundingSphere.
proc BSphere-Vec { bvType bv } {
    P "\nBSphere-Vec: $bvType Functionality: set Vector \[\$In method\]"
    PN "In $bvType" ; PBS $bv
    foreach m { center } {
        set retVal [catch {eval $bv $m} result]
        PN "Method $m"
        if { $retVal == 0 } {
            PV "$result"
        } else {
            P "Not supported ($result)"
        }
    }
    return $result
}

# Test procedure for methods not fitting into one of the above categories.
proc BSphereMisc { bvType } {
    P "\nBSphereMisc: $bvType Functionality: Miscellaneous"

    set bv1 [CreateBSphere1]
    $bv1 init
    PN "Method init" ; PBS $bv1

    $bv1 set [osg::Vec3 -args 1 2 3] 4
    PN "Method set (Vec3,4)" ; PBS $bv1

    set bv2 [$bv1 copy]
    $bv2 expandBy [osg::Vec3 -args 0 8 0]
    PN "Method expandBy Vec3" ; PBS $bv2

    set bv3 [$bv1 copy]
    $bv3 expandRadiusBy [osg::Vec3 -args 0 8 0]
    PN "Method expandRadiusBy Vec3" ; PBS $bv3

    $bv3 expandBy $bv2
    PN "Method expandBy BSphere" ; PBS $bv3

    $bv3 expandRadiusBy $bv2
    PN "Method expandRadiusBy BSphere" ; PBS $bv3

    $bv3 expandBy [osg::BoundingBox -args 1 2 3  11 12 13]
    PN "Method expandBy BBox" ; PBS $bv3

    $bv3 expandRadiusBy [osg::BoundingBox -args 1 2 3  11 12 13]
    PN "Method expandRadiusBy BBox" ; PBS $bv3

    set retVal [$bv1 contains [osg::Vec3 -args 0 1 2]]
    PN "Method contains Vec3" ; P $retVal
}

P ">>> Test cases for osg::BoundingBox class <<<\n"

set bvType osg::BoundingBox
set bv1 [$bvType -args 1 2 3  4 5 6]
set bv2 [$bvType -args 0 0 0  5 5 5]
Cnstr-BBox      $bvType
BBox-Scalar     $bvType $bv1
BBoxBBox-Scalar $bvType $bv1 $bv2
BBoxBBox-BBox   $bvType $bv1 $bv2
BBox-Vec        $bvType $bv1
BBoxMisc        $bvType
$bv1 -delete
$bv2 -delete

P "\n>>> Test cases for osg::BoundingSphere class <<<\n"

set bvType osg::BoundingSphere
set bv1 [$bvType -args [osg::Vec3 -args 1 2 3] 4]
set bv2 [$bvType -args [osg::Vec3 -args 0 0 0] 5]
Cnstr-BSphere          $bvType
BSphere-Scalar         $bvType $bv1
BSphereBSphere-Scalar  $bvType $bv1 $bv2
BSphere-Vec            $bvType $bv1
BSphereMisc            $bvType
$bv1 -delete
$bv2 -delete

exit
