Primitive scenary editor

Advanced game related topics
User avatar
minimy
Enthusiast
Enthusiast
Posts: 551
Joined: Mon Jul 08, 2013 8:43 pm
Location: off world

Primitive scenary editor

Post by minimy »

I was about to go crazy trying to make a scenario with code, I came up with the idea of making a very primitive but useful editor.
This is very green, the editor is version 0.001 :lol: , you can modify for your own use.
Was tested over PB6.21 and work. For PB6.02 change line 629 with this CameraUserControl(0,0.001)

The system is very simple. There are three main commands. With this you include a mesh or texture. You can then copy and position it as many times as you want from the editor.

This is a module, then to run any of procedures you need call the procedures in this way: deco::ini()

ini()
Start the scenary mode. You need call this at before use the other procedures.

addTextura(...)
addTextura(fileTt3d.s, repeX.f=1,repeZ.f=1, fileNormalMap.s="")
Add one texture to the memory to use with addPrimitive

addPrimitive(...)
addPrimitive(name.s="Obj", tipo.s="cube", tt3d.s="", x.f=0,y.f=0,z.f=0, colitype.i=0, scale.f=1, ang.f=0, csx.f=0,csy.f=0,csz.f=0, NoShadow.b=#False)
Add to scene an PB object Plane or cube only. tt3d is the texture to use.

add(...)
add( fileMesh.s, x.f=0,y.f=0,z.f=0, colitype.i=0, scale.f=1, angX.f=0,angY.f=0,angZ.f=0, csx.f=0,csy.f=0,csz.f=0, NoShadow.b=#False)
Add an entity to the scene.

deco::carga() is load and deco::graba() is save, you can rename

I think it serves as a starting point for a scenario editor. For now, it only works with the keyboard for editing and the mouse to select the objects.

MOUSE
Clik over any object to select.

KEYBOARD:
F Copy selected entity.
A,W,S,D move the selected object in X,Z axis. (Hold SHIFT for small step, Hold LCTRL for one step only)
Z,X move the selected object in Y axis. (Hold SHIFT for small step, Hold LCTRL for one step only)
R,T,Y Rotate selected object in axis Y,Z,X (Hold SHIFT for reverse, Hold LCTRL for one step only)
DEL Delete object from scene
N New scene, delete all.
U Set angle 0,0,0 to selected object.
P,O (todo) change object one by one, by name.
G Save the scene.
F1 Show mode normal
F2 Show entitys boxes
F3 Show collision mesh
F4 Wireframe mode
0 (cero) Shadows on Off, only 6.02. For 6.21 use pf_shadoko shaders

MODE OF USE:
1) Include all the elements you go to use in your scene with the comands add, addPrimitive, addTexture.
comment this line, you need later changing with the name of your scenary file to load it. deco::carga("nivel1newB.tscn")
In line 561 you have this 3 examples of how add your own elements. Modify with your textures and meshes.
; deco::addTextura("adobemuro.png",0.0625,0.0625)
; deco::addPrimitive("sueloDesert1","plane","adobemuro.png",0,0,0, #PB_Entity_StaticBody, 50, 0,0,0,0,#True)
; deco::add("meta_obj.mesh", 0,0,0, #PB_Entity_StaticBody, 0.0022, 0,180,0, 0,0,0, #True)



2) move, copy, and put all the entitys where you want. Make any beauty thing please! :mrgreen:

3) Press key G to save your scene the extension is tscn, but you can change.

4) After create your own scene, to load the scene in the code of your game use includeFile("scenary.pbi").
Now include in your code this line: deco::carga("mylevel.tscn"), Where mylevel.tscn is the name of your file scenary.

IMPORTANT:
When reload your scene in the editor, comment the lines add, addPrimitive, etc. because no need anymore.
If no comment then this elements are created again.


Save this file as scenary.pbi

Code: Select all

DeclareModule deco
  ;objetos 3D
  Structure deco_items_stru ;elementos del decorado creados
    enti.i
    scale.f
    entiColision.i
    visible.i
    pos.Vector3
    ang.Vector3
  EndStructure
  Structure deco_original
    name.s
    mesh.i
    enti.i
    tipo.s
    textura.s
    scale.f
    entiColision.i
    colitype.i    ;tipo de colisión (box, sphere...)
    coliSize.Vector3
    visible.b
    noShadow.b
    pos.Vector3
    ang.Vector3
    List item.deco_items_stru()
  EndStructure
  Global NewList deco.deco_original()
  Global meshCube,meshPlane,mateColision ;dummys para las colisiones
  
  ;billboards
  Structure bill_stru
    grup.i
    tt3dfile.s
    tt3d.i
    mate.i
  EndStructure
  
  ;texturas
  Structure tt3d_stru
    name.s
    tt3d.i
    tt3dnorm.i
    normname.s
    mate.i
    repeX.f
    repeZ.f
  EndStructure
  Global NewList textura.tt3d_stru()
  
  Declare   ini()
  Declare   freeEscena()
  Declare   graba()
  Declare   carga(file.s, borra.a=0)
  Declare   addTextura(fileTt3d.s, repeX.f=1,repeZ.f=1, fileNormalMap.s="")
  Declare   add( fileMesh.s, x.f=0,y.f=0,z.f=0, colitype.i=0, scale.f=1, angX.f=0,angY.f=0,angZ.f=0, csx.f=0,csy.f=0,csz.f=0, NoShadow.b=#False)
  Declare   addPrimitive(name.s="Obj", tipo.s="cube", tt3d.s="", x.f=0,y.f=0,z.f=0, colitype.i=0, scale.f=1, ang.f=0, csx.f=0,csy.f=0,csz.f=0, NoShadow.b=#False)
  
EndDeclareModule  
Module deco
  Procedure   ini()
    ;inicializa el sistema de decorados
    ;malla usada para las colisiones
    meshPlane=    CreatePlane(#PB_Any,1,1,1,1,1,1)
    meshCube=     CreateCube(#PB_Any,1)
    mateColision= CreateMaterial(#PB_Any,#Null,$ff0000)
  EndProcedure
  Procedure   freeEscena()
    ForEach deco()
      ForEach deco()\item()
        If IsEntity(deco()\item()\enti):FreeEntity(deco()\item()\enti):EndIf
        If IsEntity(deco()\item()\entiColision):FreeEntity(deco()\item()\entiColision):EndIf
      Next
      If IsEntity(deco()\enti):FreeEntity(deco()\enti):EndIf
      If IsEntity(deco()\entiColision):FreeEntity(deco()\entiColision):EndIf
      If IsMesh(deco()\mesh):FreeMesh(deco()\mesh):EndIf
    Next
    ForEach textura()
      If IsMaterial(textura()\mate):FreeMaterial(textura()\mate):EndIf
      If IsTexture(textura()\tt3d):FreeTexture(textura()\tt3d):EndIf
    Next
    ClearList(textura())
    ClearList(deco())
  EndProcedure
  Procedure   add( fileMesh.s, x.f=0,y.f=0,z.f=0, colitype.i=0, scale.f=1, angX.f=0,angY.f=0,angZ.f=0, csx.f=0,csy.f=0,csz.f=0, NoShadow.b=#False)
    ;añade entidades al escenario
    ;#PB_Entity_StaticBody, #PB_Entity_BoxBody, #PB_Entity_SphereBody, #PB_Entity_CylinderBody, #PB_Entity_ConeBody, #PB_Entity_ConvexHullBody
    Protected   enti
    Protected.b existe
    ForEach deco()
      If fileMesh= deco()\name
;         Debug "EXISTE: "+Str(existe)
        existe= #True
        Break
      EndIf
    Next
    If existe ;si se ha creado el objeto original
      enti= deco()\enti
      If IsEntity(enti)
        AddElement(deco()\item())
        deco()\item()\pos\x= x
        deco()\item()\pos\y= y
        deco()\item()\pos\z= z
        deco()\item()\ang\x= angX
        deco()\item()\ang\y= angY
        deco()\item()\ang\z= angZ
        deco()\item()\scale= scale
        deco()\item()\enti= CopyEntity(deco()\enti, #PB_Any)
        RotateEntity(deco()\item()\enti, angX,angY,angZ, #PB_Absolute)
        MoveEntity(deco()\item()\enti,x,y,z,#PB_Absolute)
        If deco()\noShadow
          EntityRenderMode(deco()\item()\enti,#PB_Shadow_None)
        EndIf
        If deco()\colitype
          If deco()\coliSize\x+deco()\coliSize\y+deco()\coliSize\z > 0
            deco()\item()\entiColision=  CreateEntity(#PB_Any,MeshID(meshCube),MaterialID(mateColision),x,y,z)
            RotateEntity(deco()\item()\entiColision, angX,angY,angZ, #PB_Absolute)
            ScaleEntity(deco()\item()\entiColision, deco()\coliSize\x,deco()\coliSize\y,deco()\coliSize\z,#PB_Absolute)
            EntityRenderMode(deco()\item()\entiColision,#PB_Shadow_None)
            CreateEntityBody(deco()\item()\entiColision, #PB_Entity_StaticBody,0,0.1,0.7);,1,0,0,0, deco()\coliSize\x,deco()\coliSize\y,deco()\coliSize\z)
            SetEntityCollisionFilter(deco()\item()\entiColision,1<<1,1<<1)
            HideEntity(deco()\item()\entiColision,1)
          Else
            CreateEntityBody(deco()\item()\enti, deco()\colitype,0,0.1,0.7)
          EndIf
          SetEntityCollisionFilter(deco()\item()\enti,1<<1,1<<1)
        EndIf
      EndIf
    Else ;si no existe el objeto original, crea uno
      AddElement(deco())
      deco()\pos\x= x
      deco()\pos\y= y
      deco()\pos\z= z
      deco()\ang\x= angX
      deco()\ang\y= angY
      deco()\ang\z= angZ
      deco()\scale= scale
      deco()\name=  fileMesh
      deco()\mesh=  LoadMesh(#PB_Any,deco()\name)
      deco()\enti=  CreateEntity(#PB_Any,MeshID(deco()\mesh),#PB_Material_None)
      ScaleEntity(deco()\enti, scale,scale,scale,#PB_Absolute)
      RotateEntity(deco()\enti, angX,angY,angZ, #PB_Absolute)
      MoveEntity(deco()\enti,x,y,z,#PB_Absolute)
      deco()\colitype=    colitype
      deco()\coliSize\x=  csx
      deco()\coliSize\y=  csy
      deco()\coliSize\z=  csz
      deco()\noShadow=    NoShadow
      If deco()\noShadow
        EntityRenderMode(deco()\enti,#PB_Shadow_None)
      EndIf
      If deco()\colitype
        If deco()\coliSize\x+deco()\coliSize\y+deco()\coliSize\z > 0 ;colisión extra con nueva entidad
          deco()\entiColision=  CreateEntity(#PB_Any,MeshID(meshCube),MaterialID(mateColision),x,y,z)
          RotateEntity(deco()\entiColision, angX,angY,angZ, #PB_Absolute)
          ScaleEntity(deco()\entiColision, deco()\coliSize\x,deco()\coliSize\y,deco()\coliSize\z,#PB_Absolute)
          CreateEntityBody(deco()\entiColision, #PB_Entity_StaticBody,0,0.1,0.7);,1,0,0,0, deco()\coliSize\x,deco()\coliSize\y,deco()\coliSize\z)
          SetEntityCollisionFilter(deco()\entiColision,1<<1,1<<1)
          HideEntity(deco()\entiColision,1)
        Else
          CreateEntityBody(deco()\enti, deco()\colitype,0,0.1,0.7)
          SetEntityCollisionFilter(deco()\enti,1<<1,1<<1)
        EndIf
      EndIf
    EndIf
    
  EndProcedure
  Procedure   addPrimitive(name.s="Obj", tipo.s="cube", tt3d.s="", x.f=0,y.f=0,z.f=0, colitype.i=0, scale.f=1, ang.f=0, csx.f=0,csy.f=0,csz.f=0, NoShadow.b=#False)
    ;añade entidades tipo (plane,cube) al escenario
    ;#PB_Entity_StaticBody, #PB_Entity_BoxBody, #PB_Entity_SphereBody, #PB_Entity_CylinderBody, #PB_Entity_ConeBody, #PB_Entity_ConvexHullBody
    Protected   enti
    Protected.b existe
    Protected.b textu
    ForEach textura()
      If textura()\name= tt3d
        textu= #True
        Break
      EndIf
    Next
    If Not textu
      AddElement(textura())
      textura()\name= tt3d
      textura()\tt3d= LoadTexture(#PB_Any,textura()\name)
      textura()\mate= CreateMaterial(#PB_Any,TextureID(textura()\tt3d))
    EndIf
    
    ;crea objetos
    ForEach deco()
      If name= deco()\name
        existe= #True
        Break
      EndIf
    Next
    
    If existe ;si se ha creado el objeto original
      If IsEntity(deco()\enti)
        ;{ copia
        AddElement(deco()\item())
        deco()\item()\pos\x= x
        deco()\item()\pos\x= y
        deco()\item()\pos\x= z
        deco()\item()\ang\y= ang
        deco()\item()\scale= scale
        Select deco()\tipo
          Case "plane"
            deco()\item()\enti= CreateEntity(#PB_Any,MeshID(meshPlane),MaterialID(textura()\mate),x,y,z)
          Case "cube"
            deco()\item()\enti= CreateEntity(#PB_Any,MeshID(meshCube),MaterialID(textura()\mate),x,y,z)
        EndSelect
        RotateEntity(deco()\item()\enti, 0,ang, 0, #PB_Absolute)
        MoveEntity(deco()\item()\enti,x,y,z,#PB_Absolute)
        ScaleEntity(deco()\item()\enti, deco()\item()\scale,deco()\item()\scale,deco()\item()\scale,#PB_Absolute)
        If deco()\noShadow
          EntityRenderMode(deco()\item()\enti,#PB_Shadow_None)
        EndIf
        If deco()\colitype
          If deco()\coliSize\x+deco()\coliSize\y+deco()\coliSize\z > 0
            deco()\item()\entiColision=  CreateEntity(#PB_Any,MeshID(meshCube),MaterialID(mateColision),x,y,z)
            RotateEntity(deco()\item()\entiColision, 0,ang, 0, #PB_Absolute)
            ScaleEntity(deco()\item()\entiColision, deco()\coliSize\x,deco()\coliSize\y,deco()\coliSize\z,#PB_Absolute)
            EntityRenderMode(deco()\item()\entiColision,#PB_Shadow_None)
            CreateEntityBody(deco()\item()\entiColision, #PB_Entity_StaticBody,0,0.1,0.7);,1,0,0,0, deco()\coliSize\x,deco()\coliSize\y,deco()\coliSize\z)
            SetEntityCollisionFilter(deco()\item()\entiColision,1<<1,1<<1)
            HideEntity(deco()\item()\entiColision,1)
          Else
            CreateEntityBody(deco()\item()\enti, deco()\colitype,0,0.1,0.7);,0,0,0)
          EndIf
          SetEntityCollisionFilter(deco()\item()\enti,1<<1,1<<1)
        EndIf
        ;}
      EndIf
    Else ;si no existe el objeto original, crea uno
      ;{ original
      AddElement(deco())
      deco()\name=    name
      deco()\tipo=    tipo
      deco()\textura= tt3d
;       deco()\mesh=  LoadMesh(#PB_Any,deco()\name)
      Select deco()\tipo
        Case "plane"
          deco()\enti= CreateEntity(#PB_Any,MeshID(meshPlane),MaterialID(textura()\mate),x,y,z)
        Case "cube"
          deco()\enti= CreateEntity(#PB_Any,MeshID(meshCube),MaterialID(textura()\mate),x,y,z)
      EndSelect
      ScaleEntity(deco()\enti, scale,scale,scale,#PB_Absolute)
      RotateEntity(deco()\enti, 0,ang, 0, #PB_Absolute)
      MoveEntity(deco()\enti,x,y,z,#PB_Absolute)
      deco()\scale=       scale
      deco()\colitype=    colitype
      deco()\coliSize\x=  csx
      deco()\coliSize\y=  csy
      deco()\coliSize\z=  csz
      deco()\noShadow=    NoShadow
      If deco()\noShadow
        EntityRenderMode(deco()\enti,#PB_Shadow_None)
      EndIf
      If deco()\colitype
        If deco()\coliSize\x+deco()\coliSize\y+deco()\coliSize\z > 0 ;colisión extra con nueva entidad
          deco()\entiColision=  CreateEntity(#PB_Any,MeshID(meshCube),MaterialID(mateColision),x,y,z)
          RotateEntity(deco()\entiColision, 0,ang, 0, #PB_Absolute)
          ScaleEntity(deco()\entiColision, deco()\coliSize\x,deco()\coliSize\y,deco()\coliSize\z,#PB_Absolute)
          CreateEntityBody(deco()\entiColision, #PB_Entity_StaticBody,0,0.1,0.7);,1,0,0,0, deco()\coliSize\x,deco()\coliSize\y,deco()\coliSize\z)
          SetEntityCollisionFilter(deco()\entiColision,1<<1,1<<1)
          HideEntity(deco()\entiColision,1)
        Else
          CreateEntityBody(deco()\enti, deco()\colitype,0,0.1,0.7)
          SetEntityCollisionFilter(deco()\enti,1<<1,1<<1)
        EndIf
      EndIf
      ;}
    EndIf
    
  EndProcedure
  Procedure   addTextura(fileTt3d.s, repeX.f=1,repeZ.f=1, fileNormalMap.s="")
    AddElement(textura())
    textura()\repeX= repeX
    textura()\repeZ= repeZ
    textura()\name= fileTt3d
    textura()\normname= fileNormalMap
    textura()\tt3d= LoadTexture(#PB_Any,textura()\name)
    If textura()\normname
      textura()\tt3dnorm= LoadTexture(#PB_Any,textura()\normname)
      textura()\mate= CreateShaderMaterial(#PB_Any,#PB_Material_BumpShader)
      MaterialShaderTexture(textura()\mate, TextureID(textura()\tt3d),TextureID(textura()\tt3dnorm),#Null,#Null)
      MaterialShaderParameter(textura()\mate,#PB_Shader_Fragment,"bumpy",#PB_Shader_Float,0.75,0,0,0)
      SetMaterialColor(textura()\mate, #PB_Material_DiffuseColor,$112233)
      MaterialShininess(textura()\mate, 10,$446688)
    Else
      textura()\mate= CreateMaterial(#PB_Any,TextureID(textura()\tt3d))
    EndIf
    ScaleMaterial(textura()\mate, 1 * textura()\repeX, 1 * textura()\repeZ)
  EndProcedure
  Procedure   graba()
    Protected.s t, file= SaveFileRequester("Graba","","Escena (.tscn)|*.tscn",0)
    If file
      If CreateFile(0, file)
        t+ "TEXTURAS"+#LF$
        ForEach textura()
          t+ textura()\name + "|"
          t+ StrF(textura()\repeX) + "|"
          t+ StrF(textura()\repeZ) + #LF$
        Next
        ForEach deco()
          t+ "OBJETO "+Str(ListIndex(deco()))+#LF$
          t+ deco()\name + "|" ;file
          t+ deco()\tipo + "|" ;plano, cubo...
          t+ deco()\textura + "|" ; si es del tipo plano, cubo, etc, debe incluir una textura
          t+ StrF(deco()\pos\x) + "|"
          t+ StrF(deco()\pos\y) + "|"
          t+ StrF(deco()\pos\z) + "|"
          t+ StrF(deco()\scale) + "|"
          t+ StrF(deco()\ang\x) + "|" ;angulo
          t+ StrF(deco()\ang\y) + "|" ;angulo
          t+ StrF(deco()\ang\z) + "|" ;angulo
          t+ Str(deco()\colitype) + "|"
          t+ StrF(deco()\coliSize\x) + "|"
          t+ StrF(deco()\coliSize\y) + "|"
          t+ StrF(deco()\coliSize\z) + "|"
          t+ Str(deco()\noShadow) + #LF$
          ForEach deco()\item()
            t+ StrF(deco()\item()\pos\x) + "|"
            t+ StrF(deco()\item()\pos\y) + "|"
            t+ StrF(deco()\item()\pos\z) + "|"
            t+ StrF(deco()\item()\scale) + "|"
            t+ StrF(deco()\item()\ang\x) + "|" ;angulo
            t+ StrF(deco()\item()\ang\y) + "|" ;angulo
            t+ StrF(deco()\item()\ang\z) + #LF$ ;angulo
          Next
        Next
        WriteString(0,t)
        CloseFile(0)
      EndIf
    EndIf
  EndProcedure
  Procedure   carga(file.s, borra.a=0)
    Protected.s t
    Protected.s name,tipo,textura
    Protected   colitype, noshadow
    Protected.f px,py,pz,scale ,ax,ay,az, cx,xy,xz
    If ReadFile(0,file)
      While Eof(0)=0
        t= ReadString(0)
        If t<>""
        Select Left(t,6)
          Case "TEXTUR"
            modo= 1
          Case "OBJETO"
            modo= 2
        EndSelect
        If Left(t,6)<>"TEXTUR" And Left(t,6)<>"OBJETO"
        Select modo
          Case 3  ;copia
;             name=        StringField(t,1,"|")
            If tipo= "plane" Or tipo="cubo"
              addPrimitive(deco()\name,tipo,textura,ValF(StringField(t,1,"|")),ValF(StringField(t,2,"|")),ValF(StringField(t,3,"|")),
                           colitype,ValF(StringField(t,4,"|")),ValF(StringField(t,6,"|")),cx,cy,cz,noshadow)
              deco()\item()\pos\x= ValF(StringField(t,1,"|"))
              deco()\item()\pos\y= ValF(StringField(t,2,"|"))
              deco()\item()\pos\z= ValF(StringField(t,3,"|"))
              deco()\item()\ang\x= ValF(StringField(t,5,"|"))
              deco()\item()\ang\y= ValF(StringField(t,6,"|"))
              deco()\item()\ang\z= ValF(StringField(t,7,"|"))
            Else
              add(deco()\name,
                  ValF(StringField(t,1,"|")),ValF(StringField(t,2,"|")),ValF(StringField(t,3,"|")),
                  deco()\colitype,ValF(StringField(t,4,"|")),ValF(StringField(t,5,"|")),ValF(StringField(t,6,"|")),ValF(StringField(t,7,"|")),
                  deco()\coliSize\x,deco()\coliSize\y,deco()\coliSize\z,deco()\noShadow)
            EndIf
          Case 1  ;textura
            addTextura(StringField(t,1,"|"), ValF(StringField(t,2,"|")),ValF(StringField(t,3,"|")),StringField(t,4,"|"))
          Case 2  ;original
            name=        StringField(t,1,"|")
            tipo=        StringField(t,2,"|")
            textura=     StringField(t,3,"|")
            px=       ValF(StringField(t,4,"|"))
            py=       ValF(StringField(t,5,"|"))
            pz=       ValF(StringField(t,6,"|"))
            scale=       ValF(StringField(t,7,"|"))
            ax=       ValF(StringField(t,8,"|"))
            ay=       ValF(StringField(t,9,"|"))
            az=       ValF(StringField(t,10,"|"))
            colitype=    Val(StringField(t,11,"|"))
            cx=  ValF(StringField(t,12,"|"))
            cy=  ValF(StringField(t,13,"|"))
            cz=  ValF(StringField(t,14,"|"))
            noshadow=    Val(StringField(t,15,"|"))
            noshadow= 1
            If tipo= "cube" Or tipo= "plane" 
              addPrimitive(name,tipo,textura, px,py,pz, colitype, scale, ay,
                           cx,cy,cz,noShadow)
            Else
              add(name, px,py,pz, colitype,scale,ax,ay,az,
                  cx,cy,cz,noShadow)
            EndIf
            modo= 3 ;pasa a las copias
        EndSelect
        EndIf
        EndIf
      Wend  
      CloseFile(0)
    EndIf
  EndProcedure
  
  
EndModule




CompilerIf #PB_Compiler_IsMainFile
  
Global renderTime

;{ sys
Global  fontLit= LoadFont(#PB_Any,"Arial",9)
Global  fontMed= LoadFont(#PB_Any,"Arial",16)
Global  fontBig= LoadFont(#PB_Any,"Arial",24)
;   If RegisterFontFile("Data/Fonts/Lyric Poetry.ttf")
;     fontGotic= LoadFont(#PB_Any,"Lyric Poetry",20, #PB_Font_HighQuality)
;   EndIf
Procedure   sprMouseCursor()
  Protected   i= CreateImage(#PB_Any,32,32,32,#PB_Image_Transparent)
  Protected   s= CreateSprite(#PB_Any,32,32,#PB_Sprite_AlphaBlending)
  StartVectorDrawing(ImageVectorOutput(i))
    VectorSourceColor($ff00ffff)
    MovePathCursor(0,0)
    AddPathLine(31,15)
    AddPathLine(31,31)
    AddPathLine(15,31)
    AddPathLine(0,0)
    FillPath()
    VectorSourceColor($440000ff);$ff0088ff)
    MovePathCursor(0,0)
    AddPathLine(31,15)
    AddPathLine(31,31)
    AddPathLine(0,0)
    FillPath()
    VectorSourceColor($ff000000)
    MovePathCursor(0,0)
    AddPathLine(31,15)
    AddPathLine(15,31)
    AddPathLine(0,0)
    StrokePath(1)
    MovePathCursor(31,15)
    AddPathLine(31,31)
    AddPathLine(15,31)
    StrokePath(1)
    VectorSourceColor($22000000)
    MovePathCursor(31,15)
    AddPathLine(31,31)
    AddPathLine(15,31)
    FillPath()
    
  StopVectorDrawing()
  StartDrawing(SpriteOutput(s))
    DrawingMode(#PB_2DDrawing_AllChannels)
    DrawAlphaImage(ImageID(i),0,0)
  StopDrawing()
  FreeImage(i)
  ProcedureReturn s
EndProcedure
Procedure   testGAME()
  If KeyboardReleased(#PB_Key_C)
    SetClipboardText("MoveCamera(camara,"+StrD(CameraX(0),2)+","+StrD(CameraY(0),2)+","+StrD(CameraZ(0),2)+",#PB_Absolute)")
  EndIf
  
  If KeyboardReleased(#PB_Key_F1)
    WorldDebug(#PB_World_DebugNone)
    CameraRenderMode(0,#PB_Camera_Textured)
  ElseIf KeyboardReleased(#PB_Key_F2)
    WorldDebug(#PB_World_DebugEntity)
  ElseIf KeyboardReleased(#PB_Key_F3)
    WorldDebug(#PB_World_DebugBody)
  ElseIf KeyboardReleased(#PB_Key_F4)
    CameraRenderMode(0,#PB_Camera_Wireframe)
  ElseIf KeyboardReleased(#PB_Key_F5)
    
  ElseIf KeyboardReleased(#PB_Key_F12)
    ClearDebugOutput()
  EndIf
EndProcedure
Procedure   CameraUserControl(camera,speed.f=0.1,smooth.f=0.1,yfixed.f=1e10)
  Static.f MouseX,Mousey,depx,depz,sdepx,sdepz,     fdf.b
  
  depx=-speed*(KeyboardPushed(#PB_Key_Left)-KeyboardPushed(#PB_Key_Right))
  depz=-speed*(KeyboardPushed(#PB_Key_Down)-KeyboardPushed(#PB_Key_Up)-MouseWheel()*40)
  If KeyboardPushed(#PB_Key_LeftShift):depx *4:depz * 4: EndIf
  MouseX = -MouseDeltaX() *  0.05
  MouseY = -MouseDeltaY() *  0.05
  RotateCamera(camera, MouseY, MouseX, 0, #PB_Relative)
  sdepx+(depx-sdepx)*smooth
  sdepz+(depz-sdepz)*smooth
  MoveCamera  (camera, sdepX, 0, -sdepz)
  If yfixed<>1e10:MoveCamera(camera,CameraX(camera),yfixed,CameraZ(camera),#PB_Absolute):EndIf
EndProcedure
Procedure   sprTxt(spr, txt1.s,txt2.s="",txt3.s="",txt4.s="", ink.l=$ff00ffff)
  StartDrawing(SpriteOutput(spr))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,0,64))
    DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
    DrawingFont(FontID(fontLit))
    DrawText(5,5,txt1,ink);,RGBA(0,0,0,0))
    DrawText(5,25,txt2,ink)
    DrawText(5,45,txt3,ink)
    DrawText(5,65,txt4,ink)
  StopDrawing()
EndProcedure
Procedure   ini3D()
InitEngine3D(#PB_Engine3D_DebugLog):InitSprite():InitKeyboard():InitMouse()
OpenWindow(0, 0,0, 1200,660, "NPC waypoint anim",#PB_Window_ScreenCentered)
; AntialiasingMode(#PB_AntialiasingMode_x6)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0),WindowHeight(0), 0, 0, 0)
  CompilerIf #PB_Compiler_Version >= 620 ;this is for new PB. Thanks miso :)
    ;{ 6.20 shader
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Main", #PB_3DArchive_FileSystem)
    Add3DArchive("datos/modelos/corvette",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/modelos/road",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/modelos/nature",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/modelos/edificios",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/texturas",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/fonts",#PB_3DArchive_FileSystem)
    Parse3DScripts() 
    ;}
  CompilerElse
    Add3DArchive("datos/modelos/corvette",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/modelos/road",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/modelos/nature",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/modelos/edificios",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/texturas",#PB_3DArchive_FileSystem)
    Add3DArchive("datos/fonts",#PB_3DArchive_FileSystem)
    Parse3DScripts() 
  CompilerEndIf
  EnableWorldPhysics(1)
  EnableWorldCollisions(1)

  WorldShadows(#PB_Shadow_Modulative,-1,RGB(128,128,128),1024)

  CreateLight(0, $ffffff,0,0,0,#PB_Light_Directional):LightDirection(0,-0.15,-1,0.15)
AmbientColor($888888)

CreateCamera(0,0,0,100,100)
MoveCamera(camara,7.14,10.25,-9.36,#PB_Absolute)
CameraLookAt(0, 0,0,0)
CameraBackColor(0,$555555)

glLineWidth_(5)
CreateLine3D(#PB_Any, -20,0,0,$0000ff, 20,0,0,$00ffff)
CreateLine3D(#PB_Any, 0,0,-20,$ff0000, 0,0,20,$ffff00)
CreateLine3D(#PB_Any, 0,0,0,$004400, 0,20,0,$00ff00)

Global  sprInfo= CreateSprite(#PB_Any,200,150,#PB_Sprite_AlphaBlending)

EndProcedure
;}

ini3D()

sprMouse= sprMouseCursor()
deco::ini()

; deco::carga("nivel1newB.tscn")
; deco::addTextura("adobemuro.png",0.0625,0.0625)
; deco::addPrimitive("sueloDesert1","plane","adobemuro.png",0,0,0, #PB_Entity_StaticBody, 50, 0,0,0,0,#True)

; deco::add("meta_obj.mesh", 0,0,0, #PB_Entity_StaticBody, 0.0022, 0,180,0, 0,0,0, #True)


listaItem.s= "casaAdobe1.mesh|casaAdobe2_obj.mesh|canion1_obj.mesh|canion2_obj.mesh|"
entiNow= 0
Global  itemOriginal=-1
Global  itemCopia=-1
itemAcrear= 1
paso.f= 1
tx2.s
tx3.s
tx4.s= StringField(listaItem, itemAcrear,"|")
tx5.s


Procedure   updateObjeto(x.f=0,y.f=0,z.f=0, ax.f=0,ay.f=0,az.f=0, sx.f=0,sy.f=0,sz.f=0)
  If itemCopia= -1
    If itemOriginal > -1
      SelectElement(deco::deco(), itemOriginal)
      deco::deco()\pos\x+   x
      deco::deco()\pos\y+   y
      deco::deco()\pos\z+   z
      deco::deco()\ang\x+   ax
      deco::deco()\ang\y+   ay
      deco::deco()\ang\z+   az
      RotateEntity(deco::deco()\enti,deco::deco()\ang\x, deco::deco()\ang\y, deco::deco()\ang\z,#PB_Absolute)
      DisableEntityBody(deco::deco()\enti,1)
      MoveEntity(deco::deco()\enti, deco::deco()\pos\x,deco::deco()\pos\y,deco::deco()\pos\z, #PB_Absolute)
      DisableEntityBody(deco::deco()\enti,0)
    EndIf
  Else
    If itemCopia > -1
      SelectElement(deco::deco(), itemOriginal)
      SelectElement(deco::deco()\item(), itemCopia)
      deco::deco()\item()\pos\x+   x
      deco::deco()\item()\pos\y+   y
      deco::deco()\item()\pos\z+   z
      deco::deco()\item()\ang\x+   ax
      deco::deco()\item()\ang\y+   ay
      deco::deco()\item()\ang\z+   az
      RotateEntity(deco::deco()\item()\enti,deco::deco()\item()\ang\x, deco::deco()\item()\ang\y, deco::deco()\item()\ang\z,#PB_Absolute)
      DisableEntityBody(deco::deco()\item()\enti,1)
      MoveEntity(deco::deco()\item()\enti, deco::deco()\pos\x,deco::deco()\pos\y,deco::deco()\pos\z, #PB_Absolute)
      DisableEntityBody(deco::deco()\item()\enti,0)
    EndIf
  EndIf
  deco::deco()\pos\x= (deco::deco()\pos\x * 100) / 100
  deco::deco()\pos\y= (deco::deco()\pos\y * 100) / 100
  deco::deco()\pos\z= (deco::deco()\pos\z * 100) / 100
  deco::deco()\ang\x= (deco::deco()\ang\x * 100) / 100
  deco::deco()\ang\y= (deco::deco()\ang\y * 100) / 100
  deco::deco()\ang\z= (deco::deco()\ang\z * 100) / 100
EndProcedure

;---- LOOP
Repeat
;   While WindowEvent():Wend
  Repeat
    ev= WindowEvent()
    If ev= #WM_RBUTTONUP
      ReleaseMouse(#False)
    EndIf
  Until ev= 0
  ExamineMouse(): ExamineKeyboard()
  
  CameraUserControl(0,0.1)
  testGAME()
  
  ;{ edicion
  If MouseButton(#PB_MouseButton_Left)
    If mlb= 0
      mlb= 1
      itemOriginal= -1
      itemCopia=    -1
      entiNow=      0
      pik= MouseRayCast(0,MouseX(),MouseY(), 1<<1 )
      If pik > 0
;         Debug pik
        ForEach deco::deco()
          If deco::deco()\enti= pik Or deco::deco()\entiColision= pik
            original= #True
            itemOriginal= ListIndex(deco::deco())
            entiNow= pik
            Debug "ORIGINAL"
            tx2= deco::deco()\name
            Break
          EndIf
          ForEach deco::deco()\item()
            If deco::deco()\item()\enti= pik Or deco::deco()\item()\entiColision= pik
              original= #False
              itemOriginal= ListIndex(deco::deco())
              itemCopia= ListIndex(deco::deco()\item())
        entiNow= pik
            Debug "COPIA "+Str(entiNow)
            tx2= "C"+Str(ListIndex(deco::deco()\item()))+"-"+deco::deco()\name
              Break 2
            EndIf
          Next
        Next
        
        CreateLine3D(1,EntityX(pik)-4,EntityY(pik)+0.1,EntityZ(pik),$ffffff, EntityX(pik)+4,EntityY(pik)+0.1,EntityZ(pik),$ffffff)
        CreateLine3D(2,EntityX(pik),EntityY(pik)+0.1,EntityZ(pik)-4,$ffffff, EntityX(pik),EntityY(pik)+0.1,EntityZ(pik)+4,$ffffff)
        CreateLine3D(3,EntityX(pik),EntityY(pik)+4,EntityZ(pik),$ffffff, EntityX(pik),EntityY(pik)-4,EntityZ(pik),$ffffff)
      Else
        If IsMesh(1):FreeMesh(1):EndIf
        If IsMesh(2):FreeMesh(2):EndIf
        If IsMesh(3):FreeMesh(3):EndIf
       entiNow= 0
      EndIf
    EndIf
  Else
    mlb= 0
  EndIf
  ;}
  
  ;--- TECLADO
  ;{ graba, nuevo, sombras
  If KeyboardReleased(#PB_Key_0) ; con sombras o sin
    sombrasAll !1
    deco::deco()\noShadow= sombrasAll
    If sombrasAll
      ForEach deco::deco()
        EntityRenderMode(deco::deco()\enti,#PB_Entity_CastShadow)
        ForEach deco::deco()\item()
          EntityRenderMode(deco::deco()\item()\enti,#PB_Entity_CastShadow)
        Next
      Next
    Else
      ForEach deco::deco()
          EntityRenderMode(deco::deco()\enti,#PB_Shadow_None)
          ForEach deco::deco()\item()
            EntityRenderMode(deco::deco()\item()\enti,#PB_Shadow_None)
          Next
      Next
    EndIf  
  EndIf
  
  If KeyboardReleased(#PB_Key_O) ; selecciona item anterior de la lista
    itemAcrear - 1:If itemAcrear < 1: itemAcrear= CountString(listaItem,"|"):EndIf
    tx4= StringField(listaItem, itemAcrear,"|")
  ElseIf KeyboardReleased(#PB_Key_P) ; selecciona item siguiente de la lista
    itemAcrear + 1:If itemAcrear > CountString(listaItem,"|"): itemAcrear=1:EndIf
    tx4= StringField(listaItem, itemAcrear,"|")
  EndIf
  
  If KeyboardReleased(#PB_Key_N) ;limpia la escena
    resp= MessageRequester("Cuidadin!!!","¿Quieres borrar la escena de los cojones?",#PB_MessageRequester_YesNo)
    If resp=#PB_MessageRequester_Yes:deco::freeEscena():EndIf
  EndIf
  
  If KeyboardReleased(#PB_Key_G)
    ReleaseMouse(#True)
    deco::graba()
  EndIf
  
  ;}
  
  If IsEntity(entiNow)
    If KeyboardReleased(#PB_Key_U)
      If itemCopia= -1
        If itemOriginal > -1
          SelectElement(deco::deco(), itemOriginal)
          deco::deco()\ang\x=   0
          deco::deco()\ang\y=   0
          deco::deco()\ang\z=   0
          DisableEntityBody(deco::deco()\enti,1)
          RotateEntity(deco::deco()\enti,deco::deco()\ang\x, deco::deco()\ang\y, deco::deco()\ang\z,#PB_Absolute)
          DisableEntityBody(deco::deco()\enti,0)
          Debug itemOriginal
        EndIf
      Else
        If itemCopia > -1
          SelectElement(deco::deco(), itemOriginal)
          SelectElement(deco::deco()\item(), itemCopia)
          deco::deco()\item()\ang\x=   0
          deco::deco()\item()\ang\y=   0
          deco::deco()\item()\ang\z=   0
          DisableEntityBody(deco::deco()\item()\enti,1)
          RotateEntity(deco::deco()\item()\enti,deco::deco()\item()\ang\x, deco::deco()\item()\ang\y, deco::deco()\item()\ang\z,#PB_Absolute)
          DisableEntityBody(deco::deco()\item()\enti,0)
        EndIf
      EndIf
    EndIf
    
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift)
      paso= 0.01
    Else
      paso= 0.1
    EndIf
    
  ;{ duplic, borra
    If KeyboardReleased(#PB_Key_Delete)
      If itemOriginal > -1
        If itemCopia = -1
          Debug "borra original"
          resp= MessageRequester("Hey!","Objeto original."+#LF$+"¿Quieres eliminarlo?",#PB_MessageRequester_YesNo)
          If resp=#PB_MessageRequester_Yes
            SelectElement(deco::deco(),itemOriginal)
            If IsEntity(deco::deco()\enti):FreeEntity(deco::deco()\enti):EndIf
            If IsEntity(deco::deco()\entiColision):FreeEntity(deco::deco()\entiColision):EndIf
            DeleteElement(deco::deco())
          EndIf
        Else
          Debug "borra copia"
          SelectElement(deco::deco(),itemOriginal)
          SelectElement(deco::deco()\item(),itemCopia)
          If IsEntity(deco::deco()\item()\enti):FreeEntity(deco::deco()\item()\enti):EndIf
          If IsEntity(deco::deco()\item()\entiColision):FreeEntity(deco::deco()\item()\entiColision):EndIf
          DeleteElement(deco::deco()\item())
        EndIf
      EndIf
      entiNow= 0
    EndIf
    
    ;---- COPIA
    If KeyboardReleased(#PB_Key_F)
      If original
        SelectElement(deco::deco(),itemOriginal)
        deco::add(deco::deco()\name, deco::deco()\pos\x,deco::deco()\pos\y,deco::deco()\pos\z,
                  deco::deco()\colitype,deco::deco()\scale, deco::deco()\ang\x,deco::deco()\ang\y,deco::deco()\ang\z,
                  deco::deco()\coliSize\x, deco::deco()\coliSize\y, deco::deco()\coliSize\z, deco::deco()\noShadow)
      Else
        SelectElement(deco::deco(),itemOriginal)
        SelectElement(deco::deco()\item(),itemCopia)
        deco::add(deco::deco()\name, deco::deco()\item()\pos\x,deco::deco()\item()\pos\y,deco::deco()\item()\pos\z,
                  deco::deco()\colitype,deco::deco()\scale, deco::deco()\item()\ang\x,deco::deco()\item()\ang\y,deco::deco()\item()\ang\z,
                  deco::deco()\coliSize\x, deco::deco()\coliSize\y, deco::deco()\coliSize\z, deco::deco()\noShadow)
      EndIf
    EndIf
    ;}
    
    
    
    If KeyboardPushed(#PB_Key_LeftControl)
      solouno= 1
    Else
      solouno= 0
    EndIf
  ;{ gira y mueve
    If solouno
      If KeyboardReleased(#PB_Key_R)
        If KeyboardReleased(#PB_Key_LeftShift)
          updateObjeto(0,0,0, 0,-1,0)
        Else
          updateObjeto(0,0,0, 0,1,0)
        EndIf
      EndIf
      If KeyboardReleased(#PB_Key_T)
        If KeyboardPushed(#PB_Key_LeftShift)
          updateObjeto(0,0,0, 0,0,-1)
        Else
          updateObjeto(0,0,0, 0,0,1)
        EndIf
      EndIf
      If KeyboardReleased(#PB_Key_Y)
        If KeyboardPushed(#PB_Key_LeftShift)
          updateObjeto(0,0,0, -1,0,0)
        Else
          updateObjeto(0,0,0, 1,0,0)
        EndIf
      EndIf
      
      If KeyboardReleased(#PB_Key_Z)
        updateObjeto(0,paso,0)
      ElseIf KeyboardReleased(#PB_Key_X)
        updateObjeto(0,-paso,0)
      EndIf
      
      If KeyboardReleased(#PB_Key_W)
        updateObjeto(0,0,paso,0)
      ElseIf KeyboardReleased(#PB_Key_S)
        updateObjeto(0,0,-paso,0)
      EndIf
      
      If KeyboardReleased(#PB_Key_A)
        updateObjeto(paso,0)
      ElseIf KeyboardReleased(#PB_Key_D)
        updateObjeto(-paso,0)
      EndIf
        
    Else
      If KeyboardPushed(#PB_Key_R)
        If KeyboardPushed(#PB_Key_LeftShift)
          updateObjeto(0,0,0, 0,-1)
        Else
          updateObjeto(0,0,0, 0,1)
        EndIf
      EndIf
      
      If KeyboardPushed(#PB_Key_T)
        If KeyboardPushed(#PB_Key_LeftShift)
          updateObjeto(0,0,0, 0,0,-1)
        Else
          updateObjeto(0,0,0, 0,0,1)
        EndIf
      EndIf
      If KeyboardPushed(#PB_Key_Y)
        If KeyboardPushed(#PB_Key_LeftShift)
          updateObjeto(0,0,0, -1,0,0)
        Else
          updateObjeto(0,0,0, 1,0,0)
        EndIf
      EndIf
      
      If KeyboardPushed(#PB_Key_Z)
        updateObjeto(0,paso,0)
      ElseIf KeyboardPushed(#PB_Key_X)
        updateObjeto(0,-paso,0)
      EndIf
      
      If KeyboardPushed(#PB_Key_W)
        updateObjeto(0,0,paso,0)
      ElseIf KeyboardPushed(#PB_Key_S)
        updateObjeto(0,0,-paso,0)
      EndIf
      
      If KeyboardPushed(#PB_Key_A)
        updateObjeto(paso,0)
      ElseIf KeyboardPushed(#PB_Key_D)
        updateObjeto(-paso,0)
      EndIf
      
    EndIf
  ;}
    
  
EndIf

  If entiNow
    CreateLine3D(1,EntityX(entiNow)-4,EntityY(entiNow)+0.1,EntityZ(entiNow),$ffffff, EntityX(entiNow)+4,EntityY(entiNow)+0.1,EntityZ(entiNow),$ffffff)
    CreateLine3D(2,EntityX(entiNow),EntityY(entiNow)+0.1,EntityZ(entiNow)-4,$ffffff, EntityX(entiNow),EntityY(entiNow)+0.1,EntityZ(entiNow)+4,$ffffff)
    CreateLine3D(3,EntityX(entiNow),EntityY(entiNow)+4,EntityZ(entiNow),$ffffff, EntityX(entiNow),EntityY(entiNow)-4,EntityZ(entiNow),$ffffff)
    If original
      If itemOriginal > -1
          SelectElement(deco::deco(),itemOriginal)
          DisableEntityBody(deco::deco()\enti,1)
          MoveEntity(deco::deco()\enti, deco::deco()\pos\x,deco::deco()\pos\y,deco::deco()\pos\z, #PB_Absolute)
          DisableEntityBody(deco::deco()\enti,0)
  
        If IsEntity(deco::deco()\entiColision):MoveEntity(deco::deco()\entiColision, deco::deco()\pos\x,deco::deco()\pos\y,deco::deco()\pos\z, #PB_Absolute):EndIf
      EndIf
    Else
      If itemCopia > -1
        SelectElement(deco::deco(),itemOriginal)
        SelectElement(deco::deco()\item(),itemCopia)
        If IsEntity(deco::deco()\item()\enti)
          MoveEntity(deco::deco()\item()\enti, deco::deco()\item()\pos\x,deco::deco()\item()\pos\y,deco::deco()\item()\pos\z, #PB_Absolute)
        EndIf
        If IsEntity(deco::deco()\item()\entiColision):MoveEntity(deco::deco()\item()\entiColision, deco::deco()\item()\pos\x,deco::deco()\item()\pos\y,deco::deco()\item()\pos\z, #PB_Absolute):EndIf
      EndIf
    EndIf
  EndIf
  ;}
  
  renderTime= RenderWorld()
  If IsEntity(entiNow)
    tx3= StrF(EntityX(entiNow),2)+" , "+StrF(EntityY(entiNow),2)+" , "+StrF(EntityZ(entiNow),2)+" , "+StrF(EntityYaw(entiNow),2)
  EndIf
  sprTxt(sprInfo,"FPS: "+Str(Engine3DStatus(#PB_Engine3D_CurrentFPS)), tx2, tx3, tx4 )
  DisplayTransparentSprite(sprInfo, 10,10)
  DisplayTransparentSprite(sprMouse, MouseX(),MouseY())
  
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
End
  
CompilerEndIf

Can add pf_shadoko shaders for better results.
This is an scenary maked with this code:
Image

For the next version...
If I can... It will be better. This was a draft to get an idea because I never take notes or plan how to make the programs, everything is in the coconut :mrgreen:

I hope it will help someone, that they make a game, that they sell it, that they become rich, that they set up an aerospace company... hmm. Wait!, that's already happened... :lol:
If translation=Error: reply="Sorry, Im Spanish": Endif
miso
Enthusiast
Enthusiast
Posts: 407
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Primitive scenary editor

Post by miso »

I'm incredibly short on time these days, but I will take a peek later. Creating tools is important, you will spend more time with these than with the actual game ;)
Post Reply