decals with 3d shapes

Started by RemiD, July 25, 2023, 13:28:40

Previous topic - Next topic

RemiD

a code example on how to implement decals with 3d shapes :

;decals with 3d shapes by RemiD 20230725-14h17m
Graphics3D( 854, 480, 32, 2 )
HidePointer()

;input
Global mxdiff%, mydiff%

;player
Global player_feet = CreatePivot()
Global player_eyes = CreatePivot() : PositionEntity( player_eyes, 0, 1.75-0.1, 0 ) : EntityParent( player_eyes, player_feet )
Global player_feetyaw#
Global player_eyespitch#

;camera
Global camera = CreateCamera() : CameraRange( camera, 0.1, 100 )

;reticle
Global reticle_image = CreateImage(4,4)
SetBuffer( ImageBuffer( reticle_image ) )
Color( 250, 250, 250 ) : Rect( 0, 0, 4, 4, True )

;fartarget (to point the bullet towards)
Global fartarget = CreatePivot()
MoveEntity( fartarget, 0, 0, +1000 )
EntityParent( fartarget, camera, True )

;gun
Global gun_mesh = CreateCylinder(8) : RotateMesh( gun_mesh, 90, 0, 0 ) : ScaleMesh( gun_mesh, 0.06/2, 0.06/2, 0.4/2 ) : PositionMesh( gun_mesh, 0, 0, +0.4/2 )
EntityColor( gun_mesh, 120, 120, 120 )
PositionEntity( gun_mesh, 0, 1.5, 0, True ) : MoveEntity( gun_mesh, 0, 0, 0 )
EntityParent( gun_mesh, player_eyes, True )

;bullets
Global xbullet = CreateCylinder(8) : RotateMesh( xbullet, 90, 0, 0 ) : ScaleMesh( xbullet, 0.04/2, 0.04/2, 0.08/2 ) : HideEntity( xbullet )
Global bulletscount%
Type Tbullet
 Field mesh
 Field r%, g%, b%
 ;Field state%
End Type

;holes (3d shape decals)
Global xhole = CreateCone(8) : RotateMesh( xhole, 90, 0, 0 ) : ScaleMesh( xhole, 0.04/2, 0.04/2, 0.01/2 ) : PositionMesh( xhole, 0, 0, 0.01/2 ) : HideEntity( xhole )
Global holescount%
Type Thole
 Field mesh
 Field r%, g%, b%
 ;Field state%
End Type

;room (floor, walls, ceiling)
room_mesh = CreateCube() : FlipMesh( room_mesh ) : ScaleMesh( room_mesh, 15.0/2, 3.0/2, 15.0/2 ) : PositionMesh( room_mesh, 15.0/2, 3.0/2,15.0/2 )
EntityColor( room_mesh, 225, 225, 225 )
EntityPickMode( room_mesh, 2 )

;furnitures
Global furniturescount%
Dim furniture_mesh(20)
For n% = 1 To 20 Step+1
 x# = Rand(0,+15-1)+0.5 : y# = 0 : z# = Rand(0,+15-1)+0.5
 furniturescount = furniturescount + 1 : i% = furniturescount
 furniture_mesh(i) = CreateCube() : sy# = Rand( 1, 3 ) : ScaleMesh( furniture_mesh(i), 1.0/2, sy/2, 1.0/2 ) : PositionMesh( furniture_mesh(i), 0, sy/2, 0 )
 PositionEntity( furniture_mesh(i), x, y, z )
 EntityPickMode( furniture_mesh(i), 2 )
Next

;light
olight = CreateLight(2) : LightRange( olight, 3.0 ) : LightColor( olight, 180, 180, 180 )
PositionEntity( olight, 7.5, 1.5, 7.5 )

PositionEntity( player_feet, 7.5, 0, 7.5 )

Global MainTimer = CreateTimer(30)

Main()

End()

Function Main()

 Repeat

  mxdiff = MouseXSpeed() : mydiff = MouseYSpeed()

  update_player()

  update_gun()

  update_bullets()

  update_holes()

  PositionEntity( camera, EntityX( player_eyes, True ), EntityY( player_eyes, True ), EntityZ( player_eyes, True ), True )
  RotateEntity( camera, EntityPitch( player_eyes, True ), EntityYaw( player_eyes, True ), EntityRoll( player_eyes, True ), True )

  WireFrame( False )
  If( KeyDown(2)=1 ) : WireFrame( True) : EndIf

  SetBuffer( BackBuffer() )
  RenderWorld()

  DrawImage( reticle_image, GraphicsWidth()/2-2, GraphicsHeight()/2-2 )

  Color( 000, 000, 250 ) : CText( bulletscount, 0, 0 )
  Color( 000, 000, 250 ) : CText( holescount, 0, 15 )

  ;flip( true)
  WaitTimer(MainTimer)
  VWait():Flip(False)

 Until( KeyDown(1)=1 )

End Function

Function CText(TextStr$,PX%,PY%)

 Text(PX,PY,TextStr,False,False)

End Function

Function Distance2D#(PAX#,PAZ#,PBX#,PBZ#)

 Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
 Return Distance2D

End Function

Function Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#)

 Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) )
 Return Distance3D

End Function

Function update_player()

 MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2)
 player_eyespitch = player_eyespitch + Float( mydiff )/10
 If( player_eyespitch < -89 )
  player_eyespitch = -89
 Else If( player_eyespitch > 89 )
  player_eyespitch = 89
 EndIf
 RotateEntity( player_eyes, player_eyespitch, 0, 0, False )
 player_feetyaw = player_feetyaw - Float( mxdiff )/10
 RotateEntity( player_feet, 0, player_feetyaw, 0, False )

 If( KeyDown(17)=1 )
  MoveEntity( player_feet, 0, 0, 0.1 )
 Else If( KeyDown(31)=1 )
  MoveEntity( player_feet, 0, 0, -0.1 )
 EndIf
 If( KeyDown(30)=1 )
  MoveEntity( player_feet, -0.1, 0, 0 )
 Else If( KeyDown(32)=1 )
  MoveEntity( player_feet, 0.1, 0, 0 )
 EndIf

End Function

Function update_gun()

 ;if mouse left button is hit
 If( MouseHit(1)=1 )
  ;create a new bullet at gun position
  bulletscount = bulletscount + 1
  bul.Tbullet = New Tbullet
  bul\mesh = CopyEntity( xbullet )
  PositionEntity( bul\mesh, EntityX( gun_mesh, True ), EntityY( gun_mesh, True ), EntityZ( gun_mesh, True ), True )
  RotateEntity( bul\mesh, EntityPitch( gun_mesh, True ), EntityYaw( gun_mesh, True ), EntityRoll( gun_mesh, True ), True )
  MoveEntity( bul\mesh, 0, 0, 0.4 )
  PointEntity( bul\mesh, fartarget, 0 )
  bul\r = Rand( 025, 250 ) : bul\g = Rand( 025, 250 ) : bul\b = Rand( 025, 250 )
  EntityColor( bul\mesh, bul\r, bul\g, bul\b )
 EndIf

End Function

Function update_bullets()

 ;for each bullet
 For bul.Tbullet = Each Tbullet

  ;check if there is an obstacle in front of the bullet, using linepick
  TFormVector( 0, 0, +0.2, bul\mesh, 0 ) ;get the global translation vector properties of the bullet
  pickent% = LinePick( EntityX(bul\mesh,True), EntityY(bul\mesh,True), EntityZ(bul\mesh,True), TFormedX(), TFormedY(), TFormedZ(), 0.04 ) ;linepick from the bullet position orientation to where the bullet will go

  ;if yes
  If ( pickent <> 0 )
  ;get the picked position (on the surface)
  pickx# = PickedX() : picky# = PickedY() : pickz# = PickedZ()
  ;get the picked normal (of the surface)
  picknx# = PickedNX() : pickny# = PickedNY() : picknz# = PickedNZ()
  ;get the color of the bullet
  r% = bul\r : g% = bul\g : b% = bul\b
  ;destroy the bullet
  FreeEntity( bul\mesh ) : Delete( bul )
  bulletscount = bulletscount - 1
  ;create a new hole (3d shape decal) at this position, oriented along this normal, with the color of the bullet
  holescount = holescount + 1
  hol.Thole = New Thole
  hol\mesh = CopyEntity( xhole )
  EntityColor( hol\mesh, r, g , b )
  PositionEntity( hol\mesh, pickx, picky, pickz, True )
  AlignToVector( hol\mesh, picknx, pickny, picknz, 3, 1.0 )

  ;if no
  Else If( PickEnt = 0 )
  ;move the bullet
  MoveEntity( bul\mesh, 0, 0, +0.2 )

  EndIf

  ;check if the bullet goes outside of the game zone (to prevent a memory leak)
  If( bul <> Null )
    D# = Distance3D( EntityX(bul\mesh,True), EntityY(bul\mesh,True), EntityZ(bul\mesh,True), 7.5, 1.5, 7.5 )
    ;if yes
    If( D > 7.5+5 )
    ;destroy the bullet
    FreeEntity( bul\mesh ) : Delete( bul )
    bulletscount = bulletscount - 1
    EndIf

  EndIf

 Next

End Function

Function update_holes()

 ;check how many holes there are (to prevent a memory leak)
 ;if there are too many holes
 If( holescount > 30 )
  ;destroy the oldest hole
  hol.Thole = First Thole
  FreeEntity( hol\mesh ) : Delete( hol )
  holescount = holescount - 1
 EndIf

End Function

markcwm

#1
Hi RemiD,

you need to strip the font formatting from your text, this could be a forum bug as it never used to do this. I had to do the same thing recently.

RemiD

i did what 'Midimaster' suggested :
when editing the post, i toggled source view (the icon with a blank sheet), then i added [ code ] ;here is the code [ / code ] 
thank you  :)