MiniB3D bug?

SLotman

Member
Joined
Jul 3, 2017
Is the entity parent system on MiniB3D broken?

I'm trying to rotate a dice using the keyboard. This is an old mesh I've used on Blitz3D and in there it works.
What I am doing:

I create a pivot and set it to parent of the 'dice entity'. Then, I rotate that pivot -90 or +90 in X or Y (pitch or yaw), the entity rotates along.
Then I REMOVE the pivot as parent, reset its rotation to 0,0,0 and add it as parent again to the dice entity.

This works flawlessly on Blitz3D. On MiniB3D on Monkey, it fails as the picture below shows: (the text is showing the dice at the top left, the pivot parent and the child 'dice entity'). Sometimes the dice won't update properly?! The weird thing is that it doesn't fail always, just sometimes on specific rotations.

I tought of gimbal lock, but forcing the pivot angles and the dice entity between 0...360 made no difference.
Using "RotateEntity" or "TurnEntity" had the same problem.
I also disabled GC, no difference.

(I'm trying this on GLFW, if it makes any difference... and I can't test it on HTML5, apparently there is something wrong with the code and it fails to compile when using no VBO)


My dice class:

Cerberus X:
Class Dice
    Field mesh:TEntity
    Field pivot:TPivot
    Field state:Int
    Field curAngle:Float, targetAngle:Float
    Field direction:Int
    Field x:Float, y:Float
 
    Method New(x:Int, y:Int, side:Int)
        mesh = CopyEntity(Resources.diceModel)
        pivot = CreatePivot()
        Self.x = x
        Self.y = y
     
        ShowEntity mesh

        Select side
            Case 1
                RotateEntity mesh, 0, -90, 0, True
            Case 2
                RotateEntity mesh, 90, 0, 0, True
            Case 3
                ' do nothing
            Case 4
                RotateEntity mesh, 180, 0, 0, True
            Case 5
                RotateEntity mesh, -90, 0, 0, True
            Case 6
                RotateEntity mesh, 0, 90, 0, True
        End Select    
        PositionEntity mesh, x, y, 0
        PositionEntity pivot, x, y, 0
     
        EntityParent mesh, pivot

        state = 0
    End Method
 
    Method update()
        Local speed:Float = 10
        Select state
            Case 0
                ' do nothing

            Case 1
                ' turning
                Select direction
                    Case Direction.UP                    
                        If curAngle <= targetAngle - speed
                            curAngle+=speed
                            'TurnEntity pivot, speed, 0, 0, True
                            RotateEntity pivot, curAngle, 0, 0
                        Else
                            state = 0
                        End If
                     
                    Case Direction.DOWN
                        If curAngle >= targetAngle + speed
                            curAngle-=speed
                            'TurnEntity pivot, -speed, 0, 0, True
                            RotateEntity pivot, curAngle, 0, 0
                        Else
                            state = 0
                        End If

                    Case Direction.LEFT
                        If curAngle >= targetAngle + speed
                            curAngle-=speed
                            'TurnEntity pivot, 0,-speed, 0, True
                            RotateEntity pivot, 0, curAngle, 0
                        Else
                            state = 0
                        End If

                    Case Direction.RIGHT
                        If curAngle <= targetAngle - speed
                            curAngle+=speed
                            'TurnEntity pivot, 0,speed, 0, True
                            RotateEntity pivot, 0, curAngle, 0
                        Else
                            state = 0
                        End If
                End Select
             
                If state = 0 Then
                    Print "::: END :::"
                End If
        End Select
    End Method
 
    Method turn(dir:Int)
        If state = 0 Then
            Self.direction = dir

            EntityParent mesh, Null        
            RotateEntity pivot, 0, 0,0
            EntityParent mesh, pivot
         
            curAngle = 0

            Select dir
                Case Direction.UP
                    targetAngle = 90
                Case Direction.DOWN
                    targetAngle = 90
                Case Direction.LEFT
                    targetAngle = -90
                Case Direction.RIGHT
                    targetAngle = 90
            End Select
            state = 1
        End If
    End Method
End Class
Am I missing something? Its been ages since I've done anything in 3D, so it might be the case. If anyone can shed a light, please do. I'm stumped here :(
 
Last edited:

SLotman

Member
Joined
Jul 3, 2017
Hmmm... same bug happens on MiniB3D on BlitzMax, so its not 'Monkey' or 'Cerberus' at fault...

Edit: It was awful back-porting this to Blitz3D, but in there it works, no glitches. So its a bug on MiniB3D both on BlitzMax AND on Monkey-X / Cerberus :(
 
Last edited:

SLotman

Member
Joined
Jul 3, 2017
Just for comparison, Blitzmax code:

Cerberus X:
SuperStrict

Import sidesign.minib3d
Graphics3D(800,600,32,2)

THardwareInfo.displayinfo()

AmbientLight 128,128,128

Local light:TLight=CreateLight()
LightColor light, 128,128,128

Global diceModel:TEntity = LoadMesh("dice.b3d")
HideEntity diceModel

Global cam:TCamera
        cam = CreateCamera()
        cam.CameraClsColor(0,0,80)
        cam.PositionEntity 0, 0, -145
        CameraRange cam, 1, 1000

Global dices:Dice[5]

dices[0] = New Dice
dices[0].Create(0,0,1)

While Not KeyHit(KEY_ESCAPE)
    dices[0].update()

    If KeyHit(KEY_LEFT) Then dices[0].turn(7)
    If KeyHit(KEY_RIGHT) Then dices[0].turn(3)
    If KeyHit(KEY_UP) Then dices[0].turn(1)
    If KeyHit(KEY_DOWN) Then dices[0].turn(5)
    
    UpdateWorld

    ' render everything normal now
    RenderWorld
    
    'Text 10,10,"FPS:" + Int(CountFPS())
    Flip 1
    Delay 1
    
Wend

Type Dice
    Field mesh:TEntity
    Field pivot:TPivot
    Field state:Int
    Field curAngle:Float, targetAngle:Float
    Field direction:Int
    Field x:Float, y:Float
    
    Method Create(x:Int, y:Int, side:Int)
        mesh = CopyEntity(diceModel)
        pivot = CreatePivot()
        Self.x = x
        Self.y = y
        
        ShowEntity mesh

        Select side
            Case 1
                RotateEntity mesh, 0, -90, 0, True
            Case 2
                RotateEntity mesh, 90, 0, 0, True
            Case 3
                ' do nothing
            Case 4
                RotateEntity mesh, 180, 0, 0, True
            Case 5
                RotateEntity mesh, -90, 0, 0, True
            Case 6
                RotateEntity mesh, 0, 90, 0, True
        End Select       
        PositionEntity mesh, x, y, 0
        PositionEntity pivot, x, y, 0
        
        EntityParent mesh, pivot

        state = 0
    End Method
    
    Method update()
        Local speed:Float = 10
        Select state
            Case 0
                ' do nothing

            Case 1
                ' turning
                Select direction
                    Case 1                       
                        If curAngle <= targetAngle - speed
                            curAngle = curAngle + speed
                            'TurnEntity pivot, speed, 0, 0, True
                            RotateEntity pivot, curAngle, 0, 0
                        Else
                            state = 0
                        End If
                        
                    Case 5
                        If curAngle >= targetAngle + speed
                            curAngle = curAngle - speed
                            'TurnEntity pivot, -speed, 0, 0, True
                            RotateEntity pivot, curAngle, 0, 0
                        Else
                            state = 0
                        End If

                    Case 7
                        If curAngle >= targetAngle + speed
                            curAngle = curAngle - speed
                            'TurnEntity pivot, 0,-speed, 0, True
                            RotateEntity pivot, 0, curAngle, 0
                        Else
                            state = 0
                        End If

                    Case 3
                        If curAngle <= targetAngle - speed
                            curAngle = curAngle + speed
                            'TurnEntity pivot, 0,speed, 0, True
                            RotateEntity pivot, 0, curAngle, 0
                        Else
                            state = 0
                        End If
                End Select
                
                If state = 0 Then
                    Print "::: END :::"
                End If
        End Select
    End Method
    
    Method turn(dir:Int)
        If state = 0 Then
            Self.direction = dir

            EntityParent mesh, Null           
            RotateEntity pivot, 0, 0,0
            EntityParent mesh, pivot
            
            curAngle = 0

            Select dir
                Case 1
                    targetAngle = 90
                Case 5
                    targetAngle = 90
                Case 7
                    targetAngle = -90
                Case 3
                    targetAngle = 90
            End Select
            state = 1
        End If
    End Method
End Type
Blitz3D code (working):
Cerberus X:
Include "..\common\keycodes.bb"

Graphics3D 800,600,32,2

AmbientLight 128,128,128

Local light=CreateLight()
LightColor light, 128,128,128

Global diceModel = LoadMesh("data/dice.b3d")
HideEntity diceModel

Global cam = CreateCamera()
        CameraClsColor(cam, 0,0,80)
        PositionEntity cam, 0, 0, -145
        CameraRange cam, 1, 1000

Dim dices.Dice(5)

dices(0) = New Dice
CreateDice(0,0,0,1)

While Not KeyHit(KEY_ESCAPE)
    updateDice(0)

    If KeyHit(KEY_LEFT) Then turnDice(0, 7)
    If KeyHit(KEY_RIGHT) Then turnDice(0,3)
    If KeyHit(KEY_UP) Then turnDice(0,1)
    If KeyHit(KEY_DOWN) Then turnDice(0,5)
    
    UpdateWorld

    ;' Render everything normal now
    RenderWorld
    
    ;'Text 10,10,"FPS:" + Int(CountFPS())
    Flip 1
    Delay 1
    
Wend

Type Dice
    Field mesh
    Field pivot
    Field state
    Field curAngle#
    Field targetAngle#
    Field direction
    Field x#, y#
End Type

Function CreateDice(index, cx, cy, side)
    dices(index)\mesh = CopyEntity(diceModel)
    dices(index)\pivot = CreatePivot()
    dices(index)\x = cx
    dices(index)\y = cy
        
    ShowEntity dices(index)\mesh

    Select side
        Case 1
            RotateEntity dices(index)\mesh, 0, -90, 0, True
        Case 2
            RotateEntity dices(index)\mesh, 90, 0, 0, True
        Case 3
            ; do nothing
        Case 4
            RotateEntity dices(index)\mesh, 180, 0, 0, True
        Case 5
            RotateEntity dices(index)\mesh, -90, 0, 0, True
        Case 6
            RotateEntity dices(index)\mesh, 0, 90, 0, True
    End Select       
    PositionEntity dices(index)\mesh, dices(index)\x, dices(index)\y, 0
    PositionEntity dices(index)\pivot, dices(index)\x, dices(index)\y, 0
        
    EntityParent dices(index)\mesh, dices(index)\pivot

    dices(index)\state = 0
End Function
    
Function updateDice(index)
    Local speed#= 10
    Select dices(index)\state
        Case 0
            ; do nothing

        Case 1
            ; turning
            Select dices(index)\direction
                Case 1                       
                    If dices(index)\curAngle <= dices(index)\targetAngle - speed
                       dices(index)\curAngle = dices(index)\curAngle + speed
                       ;TurnEntity dices(index)\pivot, dices(index)\speed, 0, 0, True
                       RotateEntity dices(index)\pivot, dices(index)\curAngle, 0, 0
                    Else
                       dices(index)\state = 0
                    End If
                        
                Case 5
                    If dices(index)\curAngle >= dices(index)\targetAngle + speed
                       dices(index)\curAngle = dices(index)\curAngle - speed
                       ;TurnEntity pivot, -speed, 0, 0, True
                       RotateEntity dices(index)\pivot, dices(index)\curAngle, 0, 0
                    Else
                       dices(index)\state = 0
                    End If

                Case 7
                    If dices(index)\curAngle >= dices(index)\targetAngle + speed
                       dices(index)\curAngle = dices(index)\curAngle - speed
                       ;TurnEntity dices(index)\pivot, 0,-dices(index)\speed, 0, True
                       RotateEntity dices(index)\pivot, 0, dices(index)\curAngle, 0
                    Else
                       dices(index)\state = 0
                    End If

                Case 3
                    If dices(index)\curAngle <= dices(index)\targetAngle - speed
                       dices(index)\curAngle = dices(index)\curAngle + speed
                       ;TurnEntity dices(index)\pivot, 0,dices(index)\speed, 0, True
                       RotateEntity dices(index)\pivot, 0, dices(index)\curAngle, 0
                    Else
                       dices(index)\state = 0
                    End If
            End Select
                
            If dices(index)\state = 0 Then
               Print "::: END :::"
            End If
    End Select
End Function
    
Function turnDice(index, dir)
    If dices(index)\state = 0 Then
       dices(index)\direction = dir
       EntityParent dices(index)\mesh, 0           
       RotateEntity dices(index)\pivot, 0, 0,0
       EntityParent dices(index)\mesh, dices(index)\pivot
            
       dices(index)\curAngle = 0

       Select dir
        Case 1
            dices(index)\targetAngle = 90
        Case 5
            dices(index)\targetAngle = -90
        Case 7
            dices(index)\targetAngle = -90
        Case 3
            dices(index)\targetAngle = 90
       End Select
       dices(index)\state = 1
    End If
End Function
 

SLotman

Member
Joined
Jul 3, 2017
Even using "OpenB3D"/ "MiniB3D-NG" function "ActTurnTo" the problem persists...
 
Last edited:

MikeHart

Administrator
Joined
Jun 19, 2017
Location
Germany
If you know the command that fails, you could compare it to the original source code of Blitz3D on GH.
 

SLotman

Member
Joined
Jul 3, 2017
I *don't* know what fails. Even if I did, the original source from B3D is for Direct-X 7, and miniB3D is OpenGL. Completely different beasts :(

I just spent the last 4 hours trying to adapt portions of OpenMaxB3D on MiniB3D, and failed.

I think OpenMaxB3D has a matrix only for rotation, and that's may be why it works there. But adding it on MiniB3D didn't help :(
 

SLotman

Member
Joined
Jul 3, 2017
Look at this... this is EntityParent from MiniB3D:
Cerberus X:
    Method EntityParent:TEntity(parent_ent:TEntity,glob:Bool=True)

        '' remove old parent

        ' get global values
        Local gpx_:Float=EntityX(True)
        Local gpy_:Float=EntityY(True)
        Local gpz_:Float=EntityZ(True)
        
        Local grx_:Float=EntityPitch(True)
        Local gry_:Float=EntityYaw(True)
        Local grz_:Float=EntityRoll(True)
        
        'Local gsx:Float=EntityScaleX(True) 'gsx is now kept
        'Local gsy:Float=EntityScaleY(True)
        'Local gsz:Float=EntityScaleZ(True)
    
        ' remove self from parent's child list
        If parent<>Null
            parent_link.Remove()
            parent=Null
        Endif

        ' entity no longer has parent, so set local values to equal global values
        ' must get global values before we reset transform matrix with UpdateMat
        px=gpx_
        py=gpy_
        pz=-gpz_
        rx=-grx_
        ry=gry_
        rz=grz_
        'sx=gsx
        'sy=gsy
        'sz=gsz
        

        
        ' No new parent
        If parent_ent=Null
            UpdateMat(True)
            Return
        Endif
        
        ' New parent
    
        If parent_ent<>Null
            
            If glob

                AddParent(parent_ent)
                'UpdateMat()

                PositionEntity(gpx_,gpy_,gpz_,True)
                RotateEntity(grx_,gry_,grz_,True)
                ScaleEntity(gsx,gsy,gsz,True)

            Else
        
                AddParent(parent_ent)
                'UpdateMat()
                
            Endif
            
        Endif
        
        Return self
    End
And THIS is the same thing, from Blitz3D:

C:
void Entity::remove(){
    if( _parent ){
        if( _parent->_children==this ) _parent->_children=_succ;
        if( _parent->_last_child==this ) _parent->_last_child=_pred;
    }else{
        if( _orphans==this ) _orphans=_succ;
        if( _last_orphan==this ) _last_orphan=_pred;
    }
    if( _succ ) _succ->_pred=_pred;
    if( _pred ) _pred->_succ=_succ;
}

void Entity::insert(){
    _succ=0;
    if( _parent ){
        if( _pred=_parent->_last_child ) _pred->_succ=this;
        else _parent->_children=this;
        _parent->_last_child=this;
    }else{
        if( _pred=_last_orphan ) _pred->_succ=this;
        else _orphans=this;
        _last_orphan=this;
    }
}

void Entity::setParent( Entity *p ){
    if( _parent==p ) return;

    remove();

    _parent=p;

    insert();

    invalidateWorld();
}
Not very useful :(
 

adamredwoods

New Member
Joined
Jun 23, 2017
It's been so long, but I remember I fixed a lot of bugs that didn't get committed to master yet. I'll see if this was one of them. Ping me again in a week if you haven't heard from me, but I'll try to dust off that old code!
 

magic

Active Member
3rd Party Module Dev
3rd Party Tool Dev
Joined
Mar 5, 2018
Great Adam. Thank you, at the moment MiniB3D cannot run in CerberusX.
 

adamredwoods

New Member
Joined
Jun 23, 2017
I found the code, but I want to get Cerberus on VSCode (which I have started). Poor Ted is lacking. I'll probably also remove the Xbox/Windows phone and Flash support to help simplify.
 
Last edited:

adamredwoods

New Member
Joined
Jun 23, 2017
I haven't gotten to the bug yet, but miniB3D has been updated to work. Testing is still on going.
I'll see if I can get to the bug next.
 
Top Bottom