Testing splines with a sausage

Everything related to 3D programming
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Testing splines with a sausage

Post by Psychophanta »

For PB6.12

Code: Select all

Global Titulo$="tip general"
If ExamineDesktops()=0:End:EndIf
Global bitplanes.a=DesktopDepth(0),RX=DesktopWidth(0)*2/3,RY=DesktopHeight(0)*2/3
InitEngine3D(#PB_Engine3D_NoLog,#PB_Compiler_Home+"Compilers\Engine3d.dll")
#ventana=1
;AntialiasingMode(#PB_AntialiasingMode_x4)
If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0:MessageRequester("Error","Can't open DirectX",0):End:EndIf
OpenWindow(#ventana,0,0,RX,RY,Titulo$,#PB_Window_BorderLess|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#ventana),0,0,RX,RY,1,0,0,#PB_Screen_WaitSynchronization)
Add3DArchive(#PB_Compiler_Home+"examples\3D\Data\Packs\desert.zip",#PB_3DArchive_Zip)
Add3DArchive(#PB_Compiler_Home+"examples\3D\Data\GUI",#PB_3DArchive_FileSystem)
Enumeration Ventanas3D
  #TextoInfoObjeto
EndEnumeration
Enumeration Luces
  #Luz
EndEnumeration
Enumeration Camaras
  #Camara
EndEnumeration
Enumeration Materiales
  #materialtuberia
EndEnumeration
Enumeration Mallas
  #MallaPSpline
  #mallatuberia
EndEnumeration
Enumeration Nodos
  #pivotcamara
  #pivottuberia
EndEnumeration
Enumeration Entidades
  #PSpline0
  #PSpline1
  #PSpline2
  #PSpline3
  #PSpline4
  #PSpline5
  #PSpline6
  #PSpline7
  #PSpline8
  #PSpline9
  #tuberia=60
EndEnumeration
Enumeration Splines
  #splinetuberia
EndEnumeration
CreateLight(#luz,$EEEEEE,4,4,2,#PB_Light_Point):SetLightColor(#luz,#PB_Light_DiffuseColor,$EEEEEE):MoveLight(#luz,4,4,2,#PB_Absolute)
CreateCamera(#camara,0,0,100,100):CreateNode(#pivotcamara,0,0,0):AttachNodeObject(#pivotcamara,CameraID(#camara)):CameraRange(#camara,0.1,1E4):CameraBackColor(#camara,$181911)
SkyBox("desert07.jpg"); o bien SkyBox("stevecube.jpg") , etc.
Structure D3DXVECTOR3
  x.f
  y.f
  z.f
EndStructure
Structure Vector3D Extends D3DXVECTOR3
  m.f;<-length(modulo)
EndStructure
Global nverticestuberia.a=200,nverticescirctuberia.a=20,npuntosbeziertuberia.a=9,grosortuberia.f=0.6,NewList puntosbeziertuberia.D3DXVECTOR3(); <- para tuberia 3D
For i.a=0 To npuntosbeziertuberia
  AddElement(puntosbeziertuberia())
  puntosbeziertuberia()\x=2*Cos(i/(npuntosbeziertuberia+1.0)*2*#PI)
  puntosbeziertuberia()\y=2*Sin(i/(npuntosbeziertuberia+1.0)*2*#PI)
  puntosbeziertuberia()\z=i/(npuntosbeziertuberia+6.0)
Next
Global.Vector3D DELTA,THETA; para puntero ratón en su uso 2D
Global.D3DXVECTOR3 pick,pickv,pos; <- para usar puntero del ratón para referir elementos 3D
Global EntidadSeleccionada.i
Procedure.b MouseButtonEdgeDetection(boton.b,estado.b)
  Static mb.b:Protected i.b=1<<boton
  If estado;<- if current key status is PUSHED
    If mb&i=0:mb|i:ProcedureReturn 1:EndIf;<- if previous key status was NOT PUSHED, then assign previous state to current one, and EXIT.
  ElseIf mb&i;<- else (if previous key status was PUSHED and current key status is NOT PUSHED):
    mb!i:ProcedureReturn -1;<- set previous key status to NOT PUSHED.
  EndIf
  ProcedureReturn 0
EndProcedure
Procedure.b KeyEdgeDetection(tecla.a,estado.b)
  Static pka.a
  If estado;<-if current key status is PUSHED
    If pka=0:pka=tecla:ProcedureReturn 1:EndIf;<-if previous key status was NOT PUSHED, then assign previous state to current one, and EXIT.
  ElseIf pka=tecla;<-else (if previous key status was PUSHED and current key status is NOT PUSHED):
    pka=0:ProcedureReturn -1;<-set previous key status to NOT PUSHED.
  EndIf
  ProcedureReturn 0
EndProcedure
Macro ProductoEscalar(a,b,ax=x,ay=y,az=z,bx=x,by=y,bz=z)
  (a#\ax#*b#\bx#+a#\ay#*b#\by#+a#\az#*b#\bz#)
EndMacro
Macro getmodulo(v,vx=x,vy=y,vz=z)
  (Sqr#ProductoEscalar(v#,v#,vx#,vy#,vz#,vx#,vy#,vz#))
EndMacro
Macro ProductoVectorial(in1,in2,out,in1x=x,in1y=y,in1z=z,in2x=x,in2y=y,in2z=z,outx=x,outy=y,outz=z); <- Calculates the vectorial product of two 3D vectors. Just modify this procedure to get the vectorial product for 4D, 5D, 6D or any dimension you need.
  out#\outx#=in1#\in1y#*in2#\in2z#-in1#\in1z#*in2#\in2y#
  out#\outy#=in1#\in1z#*in2#\in2x#-in1#\in1x#*in2#\in2z#
  out#\outz#=in1#\in1x#*in2#\in2y#-in1#\in1y#*in2#\in2x#
EndMacro
Macro ProyeccionVectorial(A,B,P,Ax=x,Ay=y,Az=z,Bx=x,By=y,Bz=z,Px=x,Py=y,Pz=z)
  P#\Pz#=ProductoEscalar(A#,B#,Ax#,Ay#,Az#,Bx#,By#,Bz#)/ProductoEscalar(B#,B#,Bx#,By#,Bz#,Bx#,By#,Bz#)
  P#\Px#=P#\Pz#*B#\Bx#
  P#\Py#=P#\Pz#*B#\By#
  P#\Pz#*B#\Bz#
EndMacro
Macro ProyeccionVectorialOrtogonal(A,B,P,Ax=x,Ay=y,Az=z,Bx=x,By=y,Bz=z,Px=x,Py=y,Pz=z)
  ProyeccionVectorial(A#,B#,P#,Ax#,Ay#,Az#,Bx#,By#,Bz#,Px#,Py#,Pz#)
  P#\Px#=A#\Ax#-P#\Px#
  P#\Py#=A#\Ay#-P#\Py#
  P#\Pz#=A#\Az#-P#\Pz#
EndMacro
Procedure.b Rotar_Vector3D_por_adicion_Angular(*fi.Vector3D,*R0.Vector3D)
  ;Esta funcion halla un vector resultado de una rotacion en el espacio de otro vector inicial.
  ;Esta funcion admite entonces, como parametros de entrada, 2 vectores:
  ; - 'Vector radio' ( *R0-> ) que se desea rotar. Este vector tiene direccion no colineal con el eje de rotación.
  ; - 'Vector angulo' ( *fi-> 'velocidad angular'-> * 'tiempo'), es el angulo en el que se rota el 'Vector radio' dado.
  ;     Su modulo indica el numero de radianes a rotar, su direccion indica el angulo en el espacio en el que se rota (eje de rotación)
  ;     su sentido indica el sentido de la rotacion
  ;NOTA: la funcion extrae el vector velocidad rectilinea y el nuevo vector radio.
  ;       se devuelve nuevo radio en el mismo parametro de entrada ( *R0-> )
  ; El resultado es:
  ; Proyección de *R0-> sobre *fi-> MÁS proyección ortogonal de *R0-> sobre *fi-> por el Cos(|fi->|) MÁS módulo de la proyección ortogonal de *R0-> sobre *fi-> por el Sen(|fi->|) por u^,
  ; siendo u-> = *fi-> X *R0-> .
  
  Protected Rt.Vector3D,u.Vector3D,P0.Vector3D
  *fi\m=ProductoEscalar(*fi,*fi)
  If *fi\m
    u\m=ProductoEscalar(*R0,*fi)/*fi\m; <- aqui lo uso como variable comodin
    *fi\m=Sqr(*fi\m)
    ;Rt-> = Proyeccion de *R0-> sobre *fi->:
    Rt\x=u\m**fi\x
    Rt\y=u\m**fi\y
    Rt\z=u\m**fi\z
    ;P0-> = proyeccion ortogonal de *R0-> sobre *fi->:
    P0\x=*R0\x-Rt\x
    P0\y=*R0\y-Rt\y
    P0\z=*R0\z-Rt\z
    P0\m=getmodulo(P0)
    If P0\m<1E-5; <= no hay giro ya que *R0-> y *fi-> son colineales:
      ProcedureReturn -1
    EndIf
    ;Calcular el producto vectorial: u-> = *fi-> X *R0-> (o por P0-> daría igual)
    u\x=*fi\y**R0\z-*fi\z**R0\y
    u\y=*fi\z**R0\x-*fi\x**R0\z
    u\z=*fi\x**R0\y-*fi\y**R0\x
    ;ahora obtener *R0-> = (Proyeccion de *R0-> sobre *fi->)-> + (cos(|*fi->|)·P0-> + |P0->|/|u->|·sin(|*fi->|)·u->)->:
    *R0\x=Rt\x
    *R0\y=Rt\y
    *R0\z=Rt\z
    Rt\x=Cos(*fi\m):Rt\y=Sin(*fi\m)
    u\m=getmodulo(u)
    P0\m*Rt\y/u\m
    *R0\x+Rt\x*P0\x+P0\m*u\x
    *R0\y+Rt\x*P0\y+P0\m*u\y
    *R0\z+Rt\x*P0\z+P0\m*u\z
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure
Macro AnimarGiroenPropioEjeXYZ(rot,tipoobjeto,objeto,grados,veloc=5)
  seno2.d=Pow(Sin(Animaciondiferencial.d),2)
;   seno2.d=1-Abs(Cos(Animaciondiferencial.d)); con este va pero el paso no es de #PI/(grados#*2/veloc#). Interesante estudiar esto matemáticamente.
  Animaciondiferencial.d+#PI/(grados#*2/veloc#)
  If Abs(Animaciondiferencial.d)>=#PI:Animaciondiferencial.d=0:AnimacionPivotCamara.b=0
  Else:rot#(tipoobjeto#ID(objeto#),Sign(grados#)*veloc#*seno2.d,#PB_Local|#PB_Relative)
  EndIf
EndMacro
Macro OrbitarObjeto1SobreObjeto0(tecla=LeftControl,tipo1=Camera,objeto1=#Camara,tipo0=Node,objeto0=#Pivotcamara); <- el 'objeto1' orbita sobre el 'objeto0', y este debe ser nodo de 'objeto1'
  If AnimacionPivotCamara.b
    Select TipodeGiro.b
    Case 1; pitch 90 grados
      AnimarGiroenPropioEjeXYZ(Pitch,tipo0#,objeto0#,Gradosdegiro.d)
    Case 2; pitch -90 grados
      AnimarGiroenPropioEjeXYZ(Pitch,tipo0#,objeto0#,Gradosdegiro.d)
    Case 3; yaw 90 grados
      AnimarGiroenPropioEjeXYZ(Yaw,tipo0#,objeto0#,Gradosdegiro.d)
    Case 4; yaw -90 grados
      AnimarGiroenPropioEjeXYZ(Yaw,tipo0#,objeto0#,Gradosdegiro.d)
    Case 5; roll 90 grados
      AnimarGiroenPropioEjeXYZ(Roll,tipo0#,objeto0#,Gradosdegiro.d)
    Case 6; roll -90 grados
      AnimarGiroenPropioEjeXYZ(Roll,tipo0#,objeto0#,Gradosdegiro.d)
    EndSelect
  Else
    If KeyboardPushed(#PB_Key_Pad0)
      Rotate#tipo0#(objeto0#,0,0,0,#PB_Absolute)
      Move#tipo1#(objeto1#,0,0,9,#PB_Absolute)
    EndIf
    estadotecla.b=KeyboardPushed(#PB_Key_#tecla#):estadoteclaf.b=KeyEdgeDetection(#PB_Key_#tecla#,estadotecla.b)
    If estadoteclaf.b>0; <- inicia control camara
      pasocam.f=0.01:pasocamincr.f=0.001
      ShowGUI(180,0,#camara,1):CursorX0.f=CursorX.f:CursorY0.f=CursorY.f
    ElseIf estadoteclaf.b<0; <- termina control camara
      ShowGUI(180,1,#camara,1)
    ElseIf estadotecla.b; <- mover el punto de vista
      MouseLocate(CursorX0.f,CursorY0.f)
      ;para desplazar la camara hacia delante, atras, arriba, abajo, izq o der
      If DELTA\m
        If mmb.b
          Move#tipo1#(objeto1#,DELTA\x/40,-DELTA\y/40,0,#PB_Local)
        Else
          Rotate#tipo0#(objeto0#,-DELTA\y/10,-DELTA\x/10,0,#PB_Relative)
          If DELTA\z
            Move#tipo1#(objeto1#,0,0,-DELTA\z,#PB_Local)
          EndIf
        EndIf
      ElseIf KeyboardPushed(#PB_Key_Add)
        Move#tipo1#(objeto1#,0,0,-pasocam,#PB_Local)
        pasocam+pasocamincr
      ElseIf KeyboardPushed(#PB_Key_Subtract)
        Move#tipo1#(objeto1#,0,0,pasocam,#PB_Local)
        pasocam+pasocamincr
      EndIf
    ElseIf KeyboardPushed(#PB_Key_Pad8)
      If KeyboardPushed(#PB_Key_Pad5)
        Gradosdegiro.d=-90
        AnimacionPivotCamara.b=1:TipodeGiro.b=1
      Else
        Pitch(tipo0#ID(objeto0#),-0.5,#PB_Local|#PB_Relative)
      EndIf
    ElseIf KeyboardPushed(#PB_Key_Pad2)
      If KeyboardPushed(#PB_Key_Pad5)
        Gradosdegiro.d=90
        AnimacionPivotCamara.b=1:TipodeGiro.b=2
      Else
        Pitch(tipo0#ID(objeto0#),0.5,#PB_Local|#PB_Relative)
      EndIf
    ElseIf KeyboardPushed(#PB_Key_Pad4)
      If KeyboardPushed(#PB_Key_Pad5)
        Gradosdegiro.d=-90
        AnimacionPivotCamara.b=1:TipodeGiro.b=3
      Else
        Yaw(tipo0#ID(objeto0#),-0.5,#PB_Local|#PB_Relative)
      EndIf
    ElseIf KeyboardPushed(#PB_Key_Pad6)
      If KeyboardPushed(#PB_Key_Pad5)
        Gradosdegiro.d=90
        AnimacionPivotCamara.b=1:TipodeGiro.b=4
      Else
        Yaw(tipo0#ID(objeto0#),0.5,#PB_Local|#PB_Relative)
      EndIf
    ElseIf KeyboardPushed(#PB_Key_Pad7)
      If KeyboardPushed(#PB_Key_Pad5)
        Gradosdegiro.d=-90
        AnimacionPivotCamara.b=1:TipodeGiro.b=5
      Else
        Roll(tipo0#ID(objeto0#),-0.5,#PB_Local|#PB_Relative)
      EndIf
    ElseIf KeyboardPushed(#PB_Key_Pad9)
      If KeyboardPushed(#PB_Key_Pad5)
        Gradosdegiro.d=90
        AnimacionPivotCamara.b=1:TipodeGiro.b=6
      Else
        Roll(tipo0#ID(objeto0#),0.5,#PB_Local|#PB_Relative)
      EndIf
    EndIf
  EndIf
EndMacro
Macro desplazardesdepuntodevista(entidad)
  ConvertLocalToWorldPosition(CameraID(#camara),THETA\x,-THETA\y,THETA\z)
  THETA\x=GetX():THETA\y=GetY():THETA\z=GetZ():THETA\m=getmodulo(THETA)
  MoveEntity(entidad#,THETA\x,THETA\y,THETA\z,#PB_World|#PB_Relative)
EndMacro
Procedure TuberiaBezier(actualizar.b=1,color.l=$43D4E2)
  Protected sp1.Vector3D,sp0.Vector3D,sp.Vector3D,vector0.Vector3D,vector.Vector3D,compas.Vector3D,radio.Vector3D,i.a,j.a,texcoordu.f,texcoordv.f,ncara.u=0,Dim primercirculo.D3DXVECTOR3(nverticescirctuberia)
  If actualizar
    ForEach puntosbeziertuberia()
      UpdateSplinePoint(#splinetuberia,ListIndex(puntosbeziertuberia()),puntosbeziertuberia()\x,puntosbeziertuberia()\y,puntosbeziertuberia()\z)
    Next
    If IsEntity(#tuberia):FreeEntity(#tuberia):EndIf; o bien si la malla va con 'node' en lugar de con 'entity': ;UpdateMesh(#mallatuberia,0)
  Else
    CreateSpline(#splinetuberia)
    CreateSphere(#MallaPSpline,0.05)
    ForEach puntosbeziertuberia()
      AddSplinePoint(#splinetuberia,puntosbeziertuberia()\x,puntosbeziertuberia()\y,puntosbeziertuberia()\z)
      CreateEntity(#PSpline0+ListIndex(puntosbeziertuberia()),MeshID(#MallaPSpline),#PB_Material_None,puntosbeziertuberia()\x,puntosbeziertuberia()\y,puntosbeziertuberia()\z)
    Next
    CreateMaterial(#materialtuberia,0,color):DisableMaterialLighting(#materialtuberia,1)
    ;Activar las 2 lineas que siguen si la malla va con 'node' en lugar de con 'entity':
;     CreateMesh(#mallatuberia,#PB_Mesh_TriangleList,#PB_Mesh_Static):SetMeshMaterial(#mallatuberia,MaterialID(#materialtuberia))
;     CreateNode(#pivottuberia):AttachNodeObject(#pivottuberia,MeshID(#mallatuberia))
  EndIf
  CreateMesh(#mallatuberia,#PB_Mesh_TriangleList,#PB_Mesh_Static):SetMeshMaterial(#mallatuberia,MaterialID(#materialtuberia)); <- quitar si la malla va con 'node' en lugar de con 'entity'
  ComputeSpline(#splinetuberia,0.0):sp\x=SplineX(#splinetuberia):sp\y=SplineY(#splinetuberia):sp\z=SplineZ(#splinetuberia); <- tiempo 0
  sp0=sp; <- inicio nulo
  FillMemory(@vector,SizeOf(Vector3D)); <- inicio nulo
  For i=0 To nverticestuberia; <- recorrer toda la linea spline; desde tiempo=0 hasta tiempo=1 en la spline
    sp1=sp0
    sp0=sp
    ComputeSpline(#splinetuberia,(i+1.0)/(nverticestuberia+1.0))
    sp\x=SplineX(#splinetuberia):sp\y=SplineY(#splinetuberia):sp\z=SplineZ(#splinetuberia)
    vector0=vector
    vector\x=sp\x-sp0\x:vector\y=sp\y-sp0\y:vector\z=sp\z-sp0\z:vector\m=getmodulo(vector); <- vector sentido del tiempo spline
    vector\x*2*#PI/vector\m/nverticescirctuberia:vector\y*2*#PI/vector\m/nverticescirctuberia:vector\z*2*#PI/vector\m/nverticescirctuberia; <- vector sentido del tiempo spline modulado
    If i
      ProyeccionVectorialOrtogonal(radio,vector,compas):compas\m=getmodulo(compas)
      ProyeccionVectorialOrtogonal(vector0,vector,radio):radio\m=getmodulo(radio)
      If radio\m<compas\m*12:radio=compas:EndIf
      radio\x*grosortuberia/2/radio\m:radio\y*grosortuberia/2/radio\m:radio\z*grosortuberia/2/radio\m
    Else
      compas\x=0:compas\y=grosortuberia/2:compas\z=0:compas\m=compas\y
      ProyeccionVectorialOrtogonal(compas,vector,radio):radio\m=getmodulo(radio)
      If radio\m<1E-2
        Swap compas\y,compas\z
        ProyeccionVectorialOrtogonal(compas,vector,radio):radio\m=getmodulo(radio)
      EndIf
      radio\x*compas\m/radio\m:radio\y*compas\m/radio\m:radio\z*compas\m/radio\m
    EndIf
    For j=0 To nverticescirctuberia
      If i=0
        primercirculo(j)\x=sp0\x+radio\x:primercirculo(j)\y=sp0\y+radio\y:primercirculo(j)\z=sp0\z+radio\z
      EndIf
      Rotar_Vector3D_por_adicion_Angular(@vector,@radio)
      MeshVertex(sp0\x+radio\x,sp0\y+radio\y,sp0\z+radio\z,texcoordu.f,texcoordv.f,color)
    Next
  Next
  ;Para no cerrar el lazo, comentar esta linea:
  For j=0 To nverticescirctuberia:MeshVertex(primercirculo(j)\x,primercirculo(j)\y,primercirculo(j)\z,texcoordu.f,texcoordv.f,color):Next
  For i=0 To nverticestuberia
    For j=1 To nverticescirctuberia
      ncara+1
      MeshFace(ncara+nverticescirctuberia+1,ncara+nverticescirctuberia,ncara)
      MeshFace(ncara+nverticescirctuberia,ncara-1,ncara)
    Next
    ncara+1
  Next
  FinishMesh(1); <- FinishMesh(0) si la malla va con 'node' en lugar de con 'entity'
;   NormalizeMesh(#mallatuberia,0)
;   UpdateMeshBoundingBox(#mallatuberia)
  CreateEntity(#tuberia,MeshID(#mallatuberia),MaterialID(#materialtuberia)); <- si la malla va con 'node' quitar esta linea
  FreeArray(primercirculo.D3DXVECTOR3())
EndProcedure
MoveNode(#Pivotcamara,0,0,0,#PB_Absolute):RotateNode(#Pivotcamara,0,0,0,#PB_Absolute)
MoveCamera(#camara,0,0,9,#PB_Absolute)
MouseLocate(RX/2,RY/2)
ShowGUI(180,1,#camara,1)
InputEvent3D(0,0,1)
wireframe.b=1:CameraRenderMode(#camara,#PB_Camera_Wireframe)
TuberiaBezier(0)
;/ BUCLE
Repeat
  Repeat:evento.i=WindowEvent()
  Until evento=#PB_Event_None
  ;
  ExamineMouse():ExamineKeyboard()
  CursorX.f=MouseX():CursorY.f=MouseY():lmb.b=MouseButton(#PB_MouseButton_Left):rmb.b=MouseButton(#PB_MouseButton_Right):mmb.b=MouseButton(#PB_MouseButton_Middle)
  DELTA\x=MouseDeltaX():DELTA\y=MouseDeltaY():DELTA\z=MouseWheel():DELTA\m=getmodulo(DELTA)
  wCursorX.f=WindowMouseX(#ventana):wCursorY.f=WindowMouseY(#ventana)
  OrbitarObjeto1SobreObjeto0(LeftControl,Camera,#camara,Node,#Pivotcamara)
  InputEvent3D(CursorX.f,CursorY.f,lmb.b); <- para el cursor del ratón nada más.
  lmbe.b=MouseButtonEdgeDetection(#PB_MouseButton_Left,lmb)
  mmbe.b=MouseButtonEdgeDetection(#PB_MouseButton_Middle,mmb)
  If lmbe.b=1 Or mmbe.b=1
    ;buscar el punto spline más cercano al puntero
    mindistanciaspuntostuberia.f=4000
    ForEach puntosbeziertuberia()
      px.f=CameraProjectionX(#Camara,puntosbeziertuberia()\x,puntosbeziertuberia()\y,puntosbeziertuberia()\z)
      py.f=CameraProjectionY(#Camara,puntosbeziertuberia()\x,puntosbeziertuberia()\y,puntosbeziertuberia()\z)
      distanciaspuntostuberia.f=Sqr(Pow(px-CursorX,2)+Pow(py-CursorY,2))
      If mindistanciaspuntostuberia>distanciaspuntostuberia
        mindistanciaspuntostuberia=distanciaspuntostuberia
        nodotuberia.a=ListIndex(puntosbeziertuberia())
      EndIf
    Next
    EntidadSeleccionada.i=#PSpline0+nodotuberia
    EntidadSeleccionada$="PSpline"+Str(nodotuberia)
    anchuratexto.u=Len(EntidadSeleccionada$)*12
    pick\x=PickX():pick\y=PickY():pick\z=PickZ()
    pos\x=EntityX(EntidadSeleccionada):pos\y=EntityY(EntidadSeleccionada):pos\z=EntityZ(EntidadSeleccionada)
    pick=pos
    OpenWindow3D(#TextoInfoObjeto,CameraProjectionX(#camara,pick\x,pick\y,pick\z),CameraProjectionY(#camara,pick\x,pick\y,pick\z),anchuratexto.u,32,"detalles objeto",#PB_Window3D_SizeGadget|#PB_Window3D_BorderLess)
    TextGadget3D(#TextoInfoObjeto,0,-1,anchuratexto.u,32,EntidadSeleccionada$)
  EndIf
  If DELTA\m And EntidadSeleccionada$ And IsWindow3D(#TextoInfoObjeto)
    THETA=DELTA:THETA\x/100:THETA\y/100:THETA\z/20:THETA\m=getmodulo(THETA)
    If lmb.b; mover
      pos\x=EntityX(EntidadSeleccionada):pos\y=EntityY(EntidadSeleccionada):pos\z=EntityZ(EntidadSeleccionada)
      pick\x=CameraProjectionX(#camara,pos\x,pos\y,pos\z);+pickv\x
      pick\y=CameraProjectionY(#camara,pos\x,pos\y,pos\z);+pickv\y
      ResizeWindow3D(#TextoInfoObjeto,pick\x,pick\y,anchuratexto.u,#PB_Ignore)
      desplazardesdepuntodevista(EntidadSeleccionada); <- mover
      If FindString(EntidadSeleccionada$,"PSpline")
        nodotuberia.a=Val(Right(EntidadSeleccionada$,1))
        SelectElement(puntosbeziertuberia(),nodotuberia)
        puntosbeziertuberia()\x+THETA\x:puntosbeziertuberia()\y+THETA\y:puntosbeziertuberia()\z+THETA\z
        TuberiaBezier()
      EndIf
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Right)
    If grosortuberia<2:grosortuberia+0.01:TuberiaBezier():EndIf
  ElseIf KeyboardPushed(#PB_Key_Left) 
    If grosortuberia>0.01:grosortuberia-0.01:TuberiaBezier():EndIf
  ElseIf KeyboardPushed(#PB_Key_Up)
    If nverticestuberia<255:nverticestuberia+1:TuberiaBezier():EndIf
  ElseIf KeyboardPushed(#PB_Key_Down)
    If nverticestuberia>npuntosbeziertuberia:nverticestuberia-1:TuberiaBezier():EndIf
  ElseIf KeyboardPushed(#PB_Key_Home)
    If nverticescirctuberia<255:nverticescirctuberia+1:TuberiaBezier():EndIf
  ElseIf KeyboardPushed(#PB_Key_End)
    If nverticescirctuberia>3:nverticescirctuberia-1:TuberiaBezier():EndIf
  ElseIf KeyboardReleased(#PB_Key_W):wireframe.b!1:If wireframe.b:CameraRenderMode(#camara,#PB_Camera_Wireframe):Else:CameraRenderMode(#camara,#PB_Camera_Textured):EndIf
  EndIf
  TimeSinceLastFrame.i=RenderWorld(50)
  FlipBuffers()
  Delay(6)
Until KeyboardPushed(#PB_Key_Escape)
;\
You can play with the sausage using keys:
leftcontrol+mousemove (to change viewpoint), #PB_Key_Right, #PB_Key_Left, #PB_Key_Up, #PB_Key_Down, #PB_Key_Home, #PB_Key_End , and #PB_Key_W for toggle wireframe view.
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
User avatar
SPH
Enthusiast
Enthusiast
Posts: 571
Joined: Tue Jan 04, 2011 6:21 pm

Re: Testing splines with a sausage

Post by SPH »

Great!
I could play with it for hours.

Good game

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Portable LENOVO ideapad 110-17ACL 64 bits
Version de PB : 6.12LTS - 64 bits
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 460
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: Testing splines with a sausage

Post by Mindphazer »

Psychophanta wrote: Fri Dec 20, 2024 6:39 pm For PB6.12
Hi Psychophanta
For PB6.12 and Windows only :wink:
MacBook Pro 16" M4 Pro - 24 Gb - MacOS 15.4.1 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Re: Testing splines with a sausage

Post by Psychophanta »

Yes, i only tested in windows, even it can be adapted for any. May be i will update it for 6.20 final, which should work in linux , apple, etc.
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Post Reply