Blitz3D+ Command Reference

AlignDecal decal,x#,y#,z#,nx#,ny#,nz#[,roll#]

Parameters

decal - decal entity created with CreateDecal

x#, y#, z# - world-space point on the surface to stamp

nx#, ny#, nz# - surface normal at that point; must be non-zero and finite

roll# (optional) - rotation of the decal image around the normal, in degrees; 0 (default)

Description

Sits a decal flush on a surface point, aimed along the surface normal.

AlignDecal does the fiddly placement maths for you: it positions the decal at x,y,z and aims its local +Z axis along the supplied normal, so the projection volume reaches into the surface and the stamp lands square on it. This is the natural partner of the picking commands - after a CameraPick or LinePick, feed it PickedX/PickedY/PickedZ and PickedNX/PickedNY/PickedNZ and the shot mark appears exactly where the ray hit, on floors, walls, ceilings or anything in between.

The decal is nudged a whisker off the surface along the normal (a tiny offset scaled to the decal's size) so it cannot z-fight with the geometry it sits on.

The optional roll spins the image around the normal - hand each bullet hole a random roll (Rnd(360)) so repeated stamps do not look cloned.

A zero-length or non-finite normal stops the program with a runtime error, as does passing an entity that is not a decal. The projection reaches DecalSize's depth into the surface, so bumpy geometry within that distance still catches the stamp.

Requires Extended mode.

See also: CreateDecal, DecalSize, CameraPick, PickedNX.

Example

; AlignDecal Example
; ------------------
; Requires Extended mode.

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

SeedRnd MilliSecs()

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

light=CreateLight()
RotateEntity light,45,45,0

; Three walls at different angles - pickable so we can read surface normals
For n=-1 To 1
    wall=CreateCube()
    ScaleEntity wall,1.8,2,0.2
    PositionEntity wall,n*3.4,0,3
    TurnEntity wall,0,n*40,0
    EntityColor wall,110,120,135
    EntityPickMode wall,2
Next

; Paint an orange splat texture in memory
splat=CreateTexture(64,64,3)
SetBuffer TextureBuffer(splat)
ClsColor 0,0,0
Cls
Color 255,80,20
Oval 6,6,52,52,True
SetBuffer BackBuffer()
Color 255,255,255

While Not KeyDown(1)

    ; Space fires a paintball through the screen centre
    If KeyHit(57) Then
        If CameraPick(camera,320,240) Then
            decal=CreateDecal(splat)
            ; AlignDecal sits the splat flush on the surface, aimed along the picked normal
            AlignDecal decal,PickedX(),PickedY(),PickedZ(),PickedNX(),PickedNY(),PickedNZ(),Rnd(360)
            hits=hits+1
        EndIf
    EndIf

    ; Arrow keys aim the camera at the different walls
    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: aim camera   Space: fire at the crosshair   Esc: exit"
    Text 0,20,"AlignDecal matches each angled wall's surface normal, with a random roll"
    Text 316,232,"+"

    Flip

Wend

End

Index