REM ***********************************************
REM Title: 3D Reflection
REM Author: 
REM Downloaded from: http://dbcc.zimnox.com/
REM ***********************************************
 
`Initial settings
Randomize Timer()
Autocam Off
 
Sync Rate 0
Sync On
 
`Indexes for vectors and matrices
ReflectionVector=2
HitPoint=3
TempVector=4
NormalVector=5
ReflectionMatrix=101
`Create required vectors and matrices
r=Make Vector3(ReflectionVector)
r=Make Vector3(HitPoint)
r=Make Vector3(TempVector)
r=Make Vector3(NormalVector)
r=Make Matrix4(ReflectionMatrix)
 
TriangleObject=1
LaserBeam=10
ReflectedLaserBeam=11
LaserLength#=500.0
MakeTriangleObject(TriangleObject, NormalVector)
Position Camera Object Position X(TriangleObject), Object Position Y(TriangleObject)+20, Object Position Z(TriangleObject)-150
 
Make Object Box LaserBeam, 1.0, 1.0, 1.0
Make Object Box ReflectedLaserBeam, 1.0, 1.0, 1.0
Color Object LaserBeam, RGB(255,0,0)
Color Object ReflectedLaserBeam, RGB(0,255,255)
 
Do
   `Camera control
   Control Camera Using Arrowkeys 0, 0.5, 1
 
   If MouseClick() And 1
      `Calculate a relative 3D coordinate from a 2D screen coordinate of mouse
      Pick Screen MouseX(), MouseY(), LaserLength#
      Set Vector3 TempVector, Get Pick Vector X(), Get Pick Vector Y(), Get Pick Vector Z()
      Normalize Vector3 TempVector, TempVector
      ToX#=Camera Position X()+Get Pick Vector X()
      ToY#=Camera Position Y()+Get Pick Vector Y()
      ToZ#=Camera Position Z()+Get Pick Vector Z()
 
      Distance#=Intersect Object(TriangleObject, Camera Position X(), Camera Position Y(), Camera Position Z(), ToX#, ToY#, ToZ#)
 
      If Distance#<>0.0
         `Hit point with environment
         Set Vector3 HitPoint, Camera Position X()+X Vector3(TempVector)*Distance#, Camera Position Y()+Y Vector3(TempVector)*Distance#, Camera Position Z()+Z Vector3(TempVector)*Distance#
         `Calculate reflection matrix
         Build Reflection Matrix4 ReflectionMatrix, X Vector3(NormalVector), Y Vector3(NormalVector), Z Vector3(NormalVector), 0.0
         `Calculate reflection vector
         Transform Coords Vector3 ReflectionVector, TempVector, ReflectionMatrix
         Normalize Vector3 ReflectionVector, ReflectionVector
 
         Show Object LaserBeam
         Show Object ReflectedLaserBeam
 
         Position Object LaserBeam, Camera Position X()+X Vector3(TempVector)*(Distance#/2.0), Camera Position Y()+Y Vector3(TempVector)*(Distance#/2.0), Camera Position Z()+Z Vector3(TempVector)*(Distance#/2.0)
         Scale Object LaserBeam, 100, 100, 100*Distance#
         Point Object LaserBeam, Camera Position X(), Camera Position Y(), Camera Position Z()
 
         Position Object ReflectedLaserBeam, X Vector3(HitPoint)+X Vector3(ReflectionVector)*((LaserLength#-Distance#)/2.0), Y Vector3(HitPoint)+Y Vector3(ReflectionVector)*((LaserLength#-Distance#)/2.0), Z Vector3(HitPoint)+Z Vector3(ReflectionVector)*((LaserLength#-Distance#)/2.0)
         Scale Object ReflectedLaserBeam, 100, 100, 100*(LaserLength#-Distance#)
         Point Object ReflectedLaserBeam, X Vector3(HitPoint), Y Vector3(HitPoint), Z Vector3(HitPoint)
      EndIf
   EndIf
 
   `Print info
   Text 10, 10, "Reflection example: Code by Dmitry K"
   Text 10, 50, "Object normal:"
   Text 10, 70, "X = "+Str$(X Vector3(NormalVector))+"  Y = "+Str$(Y Vector3(NormalVector))+" Z = "+Str$(Z Vector3(NormalVector))
   Text 10, 90, "Reflection vector:"
   Text 10, 110, "X = "+Str$(X Vector3(ReflectionVector))+" Y = "+Str$(Y Vector3(ReflectionVector))+" Z = "+Str$(Z Vector3(ReflectionVector))
   Text 10, 130, "Hit point:"
   Text 10, 150, "X = "+Str$(X Vector3(HitPoint))+" Y = "+Str$(Y Vector3(HitPoint))+" Z = "+Str$(Z Vector3(HitPoint))
 
   Sync
Loop
 
 
Function MakeTriangleObject(Object, PlaneVectorResult)
   If Object Exist(Object) Then Delete Object Object
 
   For i=1000 To 1004
      r=Make Vector3(i)
      If i<1003 Then Set Vector3 i, Rnd(200)-100, Rnd(200)-100, Rnd(200)-100
   Next i
 
   Make Object Triangle Object, X Vector3(1000), Y Vector3(1000), Z Vector3(1000), X Vector3(1001), Y Vector3(1001), Z Vector3(1001), X Vector3(1002), Y Vector3(1002), Z Vector3(1002)
 
   Subtract Vector3 1003, 1001, 1000
   Subtract Vector3 1004, 1002, 1000
   Cross Product Vector3 PlaneVectorResult, 1003, 1004
   Normalize Vector3 PlaneVectorResult, PlaneVectorResult
 
   For i=1000 To 1004
      r=Delete Vector3(i)
   Next i
EndFunction