[gelöst] MiniB3d - TurnEntity

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

Silver_Knee

Betreff: [gelöst] MiniB3d - TurnEntity

BeitragMi, Dez 03, 2014 0:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey,

In Minib3d ist ja TurnEntity anders implementiert. Ich bräuchte jetzt an einer Stelle aber die B3D-Implementierung.

Zum Testen einfach das folgende Beispielprogramm in B3D ausführen.

[syntax="bb"]Graphics3D 800,600,16,2

CreateCamera

Local cone = CreateCone()
PositionEntity cone , 0 , 0 , 10
RotateEntity cone,90,0,0

Repeat
TurnEntity cone , 0 , 1 , 0


UpdateWorld
RenderWorld
Flip

Until KeyHit(1)
End
[/code]

Der Code dreht ein Hütchen im Uhrzeigersinn. Der BMax-Code nicht.

Code: [AUSKLAPPEN]

Framework sidesign.minib3d

SuperStrict

Graphics3D 800,600,16,2
Collisions 1,2,2,2

CreateCamera

Local cone:TMesh = CreateCone()
PositionEntity cone , 0 , 0 , 10
RotateEntity cone,90,0,0

Repeat
   TurnEntity cone , 0 , 1 , 0
   
   
   UpdateWorld
   RenderWorld
   Flip
   
Until KeyHit(KEY_ESCAPE) Or AppTerminate()
End


Wenn man dem Hütchen einen Parent gibt und den Parent zuerst um 90 Grad Pitch dreht, dann bekommt man das Verhalten von B3D hin. Leider klappt das dann mit MoveEntitiy nicht mehr. so gut.

Also hab ich folgendes ausprobiert:
Code: [AUSKLAPPEN]

Global tp:TEntity=CreatePivot()

Function TurnEntity_ (entity:TEntity , p# , y# , r#)
   Local op:TEntity = GetParent(entity)
   RotateEntity tp, EntityPitch(entity), EntityYaw(entity), EntityRoll(entity)
   EntityParent entity , tp,True
   RotateEntity entity, p , y , r
   EntityParent entity , op,True
End Function


Das wird jetzt vielleicht nicht besonders schnell sein, aber ich brauche das auch nur einmal pro Frame.

Jetzt springt das Hütchen aber bei 90 Grad. Jemand ne Idee, wie man das grade biegen kann?

Greez
Silver_Knee

-- EDIT --
Krischan hat im englischen Forum eine Lösung gepostet. Besser wäre es wohl auf OpenB3D zu wechseln.
Code: [AUSKLAPPEN]
SuperStrict

Framework sidesign.minib3d

Const QuatToEulerAccuracy:Double = 1.0 / 2 ^ 512

Graphics3D 1024, 600, 32, 2

Local cam:TCamera = CreateCamera()

Local cone:TMesh = CreateCone()
PositionEntity cone , 0 , 0 , 10
RotateEntity cone, 90, 0, 0

While Not AppTerminate()

   Turn cone, 0, 1, 0
   
   If KeyHit(KEY_ESCAPE) Then End
   
   RenderWorld
   
   Flip
   
Wend

End

Function Turn(ent:TEntity, X:Float, Y:Float, Z:Float, Glob:Int = False)

   Local Pitch:Float = 0.0
   Local Yaw:Float = 0.0
   Local Roll:Float = 0.0
   
   Local Quat:TQuaternion = EulerToQuat2(0.0, 0.0, 0.0)
   Local Turn_Quat:TQuaternion = EulerToQuat2(0.0, 0.0, 0.0)
   
   If Glob=False
   
      Quat = EulerToQuat2(EntityPitch(Ent, True), EntityYaw(Ent, True), EntityRoll(Ent, True))
      Turn_Quat = EulerToQuat2(X, Y, Z)
      Quat = MultiplyQuats2(Quat, Turn_Quat)
      Quat = NormalizeQuat2(Quat)
      QuatToEuler2( Quat.x, Quat.y, Quat.z, Quat.w, Pitch, Yaw, Roll )
      RotateEntity Ent, Pitch, Yaw, Roll
   Else
   
      RotateEntity Ent, EntityPitch( Ent )+X, EntityYaw( Ent )+Y, EntityRoll( Ent )+Z
      
   EndIf
   
End Function

Function EulerToQuat2:TQuaternion(pitch:Float, yaw:Float, roll:Float)

   Local cr:Float=Cos(-roll/2.0)
   Local cp:Float=Cos(pitch/2.0)
   Local cy:Float=Cos(yaw/2.0)
   Local sr:Float=Sin(-roll/2.0)
   Local sp:Float=Sin(pitch/2.0)
   Local sy:Float=Sin(yaw/2.0)
   Local cpcy:Float=cp*cy
   Local spsy:Float=sp*sy
   Local spcy:Float = sp * cy
   Local cpsy:Float=cp*sy
   
   Local q:TQuaternion=New TQuaternion
   
   q.w:Float=cr*cpcy+sr*spsy
   q.x:Float=sr*cpcy-cr*spsy
   q.y:Float=cr*spcy+sr*cpsy
   q.z:Float=cr*cpsy-sr*spcy
   
   Return q
   
End Function

Function QuatToEuler2(x:Float,y:Float,z:Float,w:Float,pitch:Float Var,yaw:Float Var,roll:Float Var)

   Local sint:Float=(2.0*w*y)-(2.0*x*z)
   Local cost_temp:Float=1.0-(sint*sint)
   Local cost:Float

   If Abs(cost_temp)>QuatToEulerAccuracy

      cost=Sqr(cost_temp)

      Else

      cost=0.0

   EndIf

   Local sinv:Float,cosv:Float,sinf:Float,cosf:Float
   
   If Abs(cost)>QuatToEulerAccuracy
   
      sinv=((2.0*y*z)+(2.0*w*x))/cost
      cosv=(1.0-(2.0*x*x)-(2.0*y*y))/cost
      sinf=((2.0*x*y)+(2.0*w*z))/cost
      cosf=(1.0-(2.0*y*y)-(2.0*z*z))/cost
      
   Else
      
      sinv=(2.0*w*x)-(2.0*y*z)
      cosv=1.0-(2.0*x*x)-(2.0*z*z)
      sinf=0.0
      cosf=1.0
      
   EndIf
   
   pitch=ATan2(sint,cost)
   yaw=ATan2(sinf,cosf)
   roll=-ATan2(sinv,cosv)
   
End Function

Function MultiplyQuats2:TQuaternion(q1:TQuaternion, q2:TQuaternion)

   Local q:TQuaternion=New TQuaternion
   
   q.w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z
   q.x = q1.w*q2.x + q1.x*q2.w + q1.y*q2.z - q1.z*q2.y
   q.y = q1.w*q2.y + q1.y*q2.w + q1.z*q2.x - q1.x*q2.z
   q.z = q1.w*q2.z + q1.z*q2.w + q1.x*q2.y - q1.y*q2.x

   Return q

End Function

Function NormalizeQuat2:TQuaternion(q:TQuaternion)

   Local uv:Float=Sqr(q.w*q.w+q.x*q.x+q.y*q.y+q.z*q.z)

   q.w=q.w/uv
   q.x=q.x/uv
   q.y=q.y/uv
   q.z=q.z/uv

   Return q

End Function

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group