Blitz3D+ Command Reference

TFormNormal x#,y#,z#,source_entity,dest_entity

Parameters

x# - x component of the normal
y# - y component of the normal
z# - z component of the normal
source_entity - entity whose space the normal is given in, or 0 for world space
dest_entity - entity whose space to convert the normal into, or 0 for world space

Description

Converts a surface normal from one entity's coordinate space to another's, returning a length-1 result.

It works like TFormVector - rotation and scale, no position - with two extras that matter for normals: the maths compensates for non-uniform scaling so the direction stays perpendicular to the surface it came from, and the result is normalised (scaled to length 1). If TFormVector would have produced 1,2,2 (length 3), TFormNormal gives 1/3, 2/3, 2/3. Read the result with TFormedX, TFormedY and TFormedZ.

Typical use: turning a vertex normal read with VertexNX/NY/NZ into a world-space direction for lighting tricks, particle spray, or bouncing something off a surface.

See also: TFormVector, TFormPoint, TFormedX, TFormedY, TFormedZ, VertexNX.

Example

; TFormNormal Example
; -------------------

; TFormNormal works exactly like TFormVector, then scales the result
; to length 1 - just what you want for surface normals. The local
; direction (1,1,0) has length Sqr(2), but after TFormNormal the
; world-space result always has length 1, however the rock tumbles.

Graphics3D 640,480
SetBuffer BackBuffer()

camera=CreateCamera()
PositionEntity camera,0,0,-6

light=CreateLight()
RotateEntity light,30,40,0

; A tumbling rock
rock=CreateSphere()
ScaleMesh rock,1.4,0.9,1.1
EntityColor rock,150,130,110

; A fullbright marker shows where the transformed normal points
marker=CreateSphere()
ScaleEntity marker,0.15,0.15,0.15
EntityColor marker,255,255,0
EntityFX marker,1

While Not KeyDown(1)

    TurnEntity rock,0.3,1,0.7

    ; The documented command: local direction (1,1,0) -> a unit-length
    ; world-space normal
    TFormNormal 1,1,0,rock,0

    ; Place the marker 2.5 units from the rock's centre along the normal
    PositionEntity marker,TFormedX()*2.5,TFormedY()*2.5,TFormedZ()*2.5

    ; Confirm the promise: the result's length is always 1
    length#=Sqr(TFormedX()*TFormedX()+TFormedY()*TFormedY()+TFormedZ()*TFormedZ())

    ; Arrow keys move the camera
    If KeyDown(200) Then MoveEntity camera,0,0,0.1
    If KeyDown(208) Then MoveEntity camera,0,0,-0.1
    If KeyDown(203) Then TurnEntity camera,0,1,0
    If KeyDown(205) Then TurnEntity camera,0,-1,0

    RenderWorld

    Text 0,0,"Arrow keys: move camera   Esc: exit"
    Text 0,20,"TFormNormal 1,1,0,rock,0 = "+TFormedX()+", "+TFormedY()+", "+TFormedZ()
    Text 0,40,"Length of result = "+length+" (always 1)"

    Flip

Wend

End

Index