blitz-research / monkey2

zlib License
133 stars 42 forks source link

Weird jumping/flickering sprites problem #434

Open DruggedBunny opened 5 years ago

DruggedBunny commented 5 years ago

Hi Mark,

Bit of an odd one I've run into while trying to convert my rocket smoke from cubes to sprites, sort of narrowed it down to the sample below.

In short, I'm firing a stream of physics-controlled particles that cycles through white, yellow, orange, red, black, then fade out. It should look like this (extreme debug version using cubes):

particles

However, when using sprites, they start out correctly, then once a few of them are active at once, they start to flicker and jump.

You should be able to see it in the code below. Note that the class is duplicated, just that one uses cubes, other uses sprites.

Hold Space for a constant stream and note the cubes are fine, but the sprites start jumping and flickering. With short taps, the sprites are also OK, but held for a little longer, they start to mess up. (Tap Enter for single particles and note they only screw up if tapped rapidly.)

Thought it was some sort of alpha problem, but replacing alpha with a dummy variable (leaving entity alpha at 1.0 throughout) does the same thing.


Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..

' ---------------------- SPRITE version ----------------------

Class RocketParticle_Sprite Extends Behaviour

    Public

        Function Create:RocketParticle_Sprite (parent:Entity, thrust:Vec3f, size:Float = 0.5, fadeout:Float = 0.95)

'Game.MainCamera.CameraDistance = 4.0
            'RocketParticle.SpriteInit ()

            Local sprite:Sprite = New Sprite (New SpriteMaterial (), parent)

                Cast <SpriteMaterial> (sprite.Material).ColorFactor = Color.White

                'sprite.Move (Rnd (-0.1, 0.1), Rnd (-2.1, -2.5), Rnd (-0.1, 0.1))

                sprite.Move (0.0, -2.1, 0.0)

                sprite.Parent               = Null
                sprite.Scale                = New Vec3f (size, size, 0.0)
                sprite.Alpha                = 1.0

            Local sp:RocketParticle_Sprite          = New RocketParticle_Sprite (sprite)

                sp.thrust                   = thrust
                sp.update_fader             = fadeout

                sp.TMP_fake_alpha = 1.0

            Return sp

        End

    Private

        Method New (entity:Entity)

            Super.New (entity)

            AddInstance ()

        End

        Method OnStart () Override

            Local collider:BoxCollider  = Entity.AddComponent <BoxCollider> () ' Unexpected: Collider needs to be added BEFORE applying impulse!

            Local body:RigidBody        = Entity.AddComponent <RigidBody> ()
' No Boxf!
                body.Mass               = 0.01
                body.Restitution        = 0.5
                body.Friction           = 0.1

                body.CollisionMask      = 0'COLL_NOTHING

                body.ApplyImpulse (thrust)

                thrust                  = Null ' Don't need to keep temp Vec3f object

        End

        Method OnUpdate (elapsed:Float) Override

        '       Print Int (color_change * 5.0)

'               Cast <Sprite> (Entity).Material = SpriteMat [Int (Entity.Alpha * 5.0)] ' There are 5 sprite materials

'               Local sm:SpriteMaterial = Cast <SpriteMaterial> (Cast <Sprite> (Entity).Material)

                Local cs:Sprite = Cast <Sprite> (Entity)
                Local sm:SpriteMaterial = Cast <SpriteMaterial> (cs.Material)

'               Local cs:Model  = Cast <Model> (Entity)
'               Local sm:PbrMaterial    = Cast <PbrMaterial> (cs.Material)

                Select Int (color_change * 5.0) ' There are 5 sprite materials
                    Case 0
                        sm.ColorFactor = Color.Black
                    Case 1
                        sm.ColorFactor = Color.Red
                    Case 2
                        sm.ColorFactor = Color.Orange
                    Case 3
                        sm.ColorFactor = Color.Yellow
                    Case 4
                        sm.ColorFactor = Color.White
                End

                If sm.ColorFactor = Color.Black
                    Entity.Alpha = Entity.Alpha * 0.975 ' TODO: Needs adjusting for framerate!
                    'TMP_fake_alpha = TMP_fake_alpha * 0.975
                Else
                    color_change = color_change * update_fader ' TODO: Needs adjusting for framerate!
                End

                ' Slow particle down (air resistance)... very dependent on start speed and alpha fade amount...

                Entity.GetComponent <RigidBody> ().LinearDamping = (1.0 - color_change)' * 0.95 ' Trial and error!

                'If TMP_fake_alpha < 0.075'
                If Entity.Alpha < 0.075
                    Entity.Destroy ()
                Endif

        End

        ' Rocket thrust level -- need to temp-store here as OnStart can't be passed custom params!

        Field thrust:Vec3f
        Field update_fader:Float
        Field color_change:Float = 0.99

        Field TMP_fake_alpha:Float
End

' ---------------------- MESH version ----------------------

Class RocketParticle_Mesh Extends Behaviour

    Public

        Function Create:RocketParticle_Mesh (parent:Entity, thrust:Vec3f, size:Float = 0.5, fadeout:Float = 0.95)

'Game.MainCamera.CameraDistance = 4.0
            'RocketParticle.SpriteInit ()

'           Local sprite:Sprite = New Sprite (New SpriteMaterial (), rocket.RocketModel)
            Local sprite:Model = Model.CreateBox (New Boxf (-0.5, -0.5, -0.5, 0.5, 0.5, 0.5), 1, 1, 1, New PbrMaterial (Color.White), parent)'New Sprite (New SpriteMaterial (), rocket.RocketModel)

'               Cast <SpriteMaterial> (sprite.Material).ColorFactor = Color.White

                'sprite.Move (Rnd (-0.1, 0.1), Rnd (-2.1, -2.5), Rnd (-0.1, 0.1))

                sprite.Move (0.0, -2.1, 0.0)

                sprite.Parent               = Null
                sprite.Scale                = New Vec3f (size, size, size)
                sprite.Alpha                = 1.0

            Local sp:RocketParticle_Mesh            = New RocketParticle_Mesh (sprite)

                sp.thrust                   = thrust
                sp.update_fader             = fadeout

                sp.TMP_fake_alpha = 1.0

            Return sp

        End

    Private

        Method New (entity:Entity)

            Super.New (entity)

            AddInstance ()

        End

        Method OnStart () Override

            Local collider:BoxCollider  = Entity.AddComponent <BoxCollider> () ' Unexpected: Collider needs to be added BEFORE applying impulse!

            Local body:RigidBody        = Entity.AddComponent <RigidBody> ()
' No Boxf!
                body.Mass               = 0.01
                body.Restitution        = 0.5
                body.Friction           = 0.1

                body.CollisionMask      = 0'COLL_NOTHING

                body.ApplyImpulse (thrust)

                thrust                  = Null ' Don't need to keep temp Vec3f object

        End

        Method OnUpdate (elapsed:Float) Override

        '       Print Int (color_change * 5.0)

'               Cast <Sprite> (Entity).Material = SpriteMat [Int (Entity.Alpha * 5.0)] ' There are 5 sprite materials

'               Local sm:SpriteMaterial = Cast <SpriteMaterial> (Cast <Sprite> (Entity).Material)

'               Local cs:Sprite = Cast <Sprite> (Entity)
'               Local sm:SpriteMaterial = Cast <SpriteMaterial> (cs.Material)

                Local cs:Model  = Cast <Model> (Entity)
                Local sm:PbrMaterial    = Cast <PbrMaterial> (cs.Material)

                Select Int (color_change * 5.0) ' There are 5 sprite materials
                    Case 0
                        sm.ColorFactor = Color.Black
                    Case 1
                        sm.ColorFactor = Color.Red
                    Case 2
                        sm.ColorFactor = Color.Orange
                    Case 3
                        sm.ColorFactor = Color.Yellow
                    Case 4
                        sm.ColorFactor = Color.White
                End

                If sm.ColorFactor = Color.Black
                    Entity.Alpha = Entity.Alpha * 0.975 ' TODO: Needs adjusting for framerate!
                '   TMP_fake_alpha = TMP_fake_alpha * 0.975
                Else
                    color_change = color_change * update_fader ' TODO: Needs adjusting for framerate!
                End

                ' Slow particle down (air resistance)... very dependent on start speed and alpha fade amount...

                Entity.GetComponent <RigidBody> ().LinearDamping = (1.0 - color_change)' * 0.95 ' Trial and error!

                'If TMP_fake_alpha < 0.075'
                If Entity.Alpha < 0.075
                    Entity.Destroy ()
                Endif

        End

        ' Rocket thrust level -- need to temp-store here as OnStart can't be passed custom params!

        Field thrust:Vec3f
        Field update_fader:Float
        Field color_change:Float = 0.99

        Field TMP_fake_alpha:Float
End

Class MyWindow Extends Window

    Field _scene:Scene
    Field _camera:Camera
    Field _light:Light
    Field _ground:Model

    Field pivot0:Pivot
    Field pivot1:Pivot

    Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

        Super.New( title,width,height,flags )
    End

    Method OnCreateWindow() Override

        'create (current) scene
        _scene=New Scene
        _scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
        _scene.AmbientLight = _scene.ClearColor * 0.25
        _scene.FogColor = _scene.ClearColor
        _scene.FogNear = 1.0
        _scene.FogFar = 200.0

        'create camera
        _camera=New Camera( Self )
        _camera.AddComponent<FlyBehaviour>()
        _camera.Move( 0,2.5,-5 )
        _camera.Rotate (-25, 0, 0)

        'create light
        _light=New Light
        _light.CastsShadow=True
        _light.Rotate( 45, 45, 0 )

        'create ground
        Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
        Local groundMaterial:=New PbrMaterial( Color.Lime )
        _ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
        _ground.CastsShadow=False

        pivot0 = New Pivot
        pivot0.Move (-3, 7.5, 0)

        pivot1 = New Pivot
        pivot1.Move (3, 7.5, 0)

    End

    Method OnRender( canvas:Canvas ) Override

        Local spread:Float = 0.025

        If Keyboard.KeyHit (Key.Enter)
            RocketParticle_Mesh.Create (pivot0, New Vec3f (Rnd (-spread, spread), 0.1, Rnd (-spread, spread)))
            RocketParticle_Sprite.Create (pivot1, New Vec3f (Rnd (-spread, spread), 0.1, Rnd (-spread, spread)))
        Endif

        If Keyboard.KeyDown (Key.Space)
            For Local loop:Int = 1 To 1
                RocketParticle_Mesh.Create (pivot0, New Vec3f (Rnd (-spread, spread), 0.1, Rnd (-spread, spread)))
                RocketParticle_Sprite.Create (pivot1, New Vec3f (Rnd (-spread, spread), 0.1, Rnd (-spread, spread)))
            Next
        Endif

        If Keyboard.KeyHit (Key.Escape) Then App.Terminate ()
        RequestRender()
        _scene.Update()
        _camera.Render( canvas )
        canvas.DrawText( "FPS="+App.FPS,0,0 )
        canvas.DrawText( "SPACE: Stream of particles",0,20 )
        canvas.DrawText( "ENTER: Single particles",0,40 )
        canvas.DrawText( "RocketParticle_Mesh on left",0,80 )
        canvas.DrawText( "RocketParticle_Sprite on right",0,100 )
    End

End

Function Main()

    New AppInstance

    New MyWindow

    App.Run()
End
DruggedBunny commented 5 years ago

Tried a non-physics version, and this doesn't suffer from the same problem, though it does (possibly related?) have a weird colour-changing effect on cycling the alpha, which may be another bug:

Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..

Const RadDivider:Float = Pi / 180.0

Function Degrees:Float (radian:Float)
    Return radian * RadDivider
End

Class MovingSprite
    Field sprite:Sprite
End

Class MyWindow Extends Window

    Field _scene:Scene
    Field _camera:Camera
    Field _light:Light
    Field _ground:Model

    Field list:List <MovingSprite>

    Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

        Super.New( title,width,height,flags )
    End

    Method OnCreateWindow() Override

        'create (current) scene
        _scene=New Scene
        _scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
        _scene.AmbientLight = _scene.ClearColor * 0.25
        _scene.FogColor = _scene.ClearColor
        _scene.FogNear = 1.0
        _scene.FogFar = 200.0

        'create camera
        _camera=New Camera( Self )
        _camera.AddComponent<FlyBehaviour>()
        _camera.Move( 0,2.5,-5 )

        'create light
        _light=New Light
        _light.CastsShadow=True
        _light.Rotate( 45, 45, 0 )

        'create ground
        Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
        Local groundMaterial:=New PbrMaterial( Color.Lime )
        _ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
        _ground.CastsShadow=False

        list = New List <MovingSprite>

        For Local loop:Int = 1 To 1000
            Local ms:MovingSprite = New MovingSprite
            ms.sprite = New Sprite (New SpriteMaterial)
            Cast <SpriteMaterial> (ms.sprite.Material).ColorFactor = Color.Rnd ()
            ms.sprite.Move (Rnd (-10, 10), Rnd (-10, 10), Rnd (-10, 10))
            ms.sprite.Rotate (Rnd (-180, 180), Rnd (-180, 180), Rnd (-180, 180))
            list.Add (ms)
        Next

    End

    Method OnRender( canvas:Canvas ) Override

        For Local ms:MovingSprite = Eachin list
            ms.sprite.Move (Sin (Degrees (Millisecs ())) * 0.1, Cos (Degrees (Millisecs ())) * 0.1, Sin (Degrees (Millisecs ())) * 0.1)
            ms.sprite.Alpha = Sin (Degrees (Millisecs () * 0.1))
        Next

        If Keyboard.KeyHit (Key.Escape) Then App.Terminate ()
        RequestRender()
        _scene.Update()
        _camera.Render( canvas )
        canvas.DrawText( "FPS="+App.FPS,0,0 )
    End

End

Function Main()

    New AppInstance

    New MyWindow

    App.Run()
End
blitz-research commented 5 years ago

Nice bug!

Fix is now up in develop branch...

A quick hint: instead of creating a new material for each sprite, you should try to share materials as much as possible. If each sprite has its own material, the renderer is forced to render sprites one-by-one instead of batching them for bulk rendering.

I've also added a SpriteMode.Fixed for using sprites to draw plain quads.

Haven't looked at the related material bug yet...

On Mon, Oct 15, 2018 at 8:51 AM DruggedBunny notifications@github.com wrote:

Tried a non-physics version, and this doesn't suffer from the same problem, though it does (possibly related?) have a weird colour-changing effect on cycling the alpha, which may be another bug:

Namespace myapp3d

Import ""

Import ""

Import ""

Using std.. Using mojo.. Using mojo3d..

Const RadDivider:Float = Pi / 180.0

Function Degrees:Float (radian:Float) Return radian * RadDivider End

Class MovingSprite Field sprite:Sprite End

Class MyWindow Extends Window

Field _scene:Scene Field _camera:Camera Field _light:Light Field _ground:Model

Field list:List

Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

  Super.New( title,width,height,flags )

End

Method OnCreateWindow() Override

  'create (current) scene
  _scene=New Scene
  _scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
  _scene.AmbientLight = _scene.ClearColor * 0.25
  _scene.FogColor = _scene.ClearColor
  _scene.FogNear = 1.0
  _scene.FogFar = 200.0

  'create camera
  _camera=New Camera( Self )
  _camera.AddComponent<FlyBehaviour>()
  _camera.Move( 0,2.5,-5 )

  'create light
  _light=New Light
  _light.CastsShadow=True
  _light.Rotate( 45, 45, 0 )

  'create ground
  Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
  Local groundMaterial:=New PbrMaterial( Color.Lime )
  _ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
  _ground.CastsShadow=False

  list = New List <MovingSprite>

  For Local loop:Int = 1 To 1000
      Local ms:MovingSprite = New MovingSprite
      ms.sprite = New Sprite (New SpriteMaterial)
      Cast <SpriteMaterial> (ms.sprite.Material).ColorFactor = Color.Rnd ()
      ms.sprite.Move (Rnd (-10, 10), Rnd (-10, 10), Rnd (-10, 10))
      ms.sprite.Rotate (Rnd (-180, 180), Rnd (-180, 180), Rnd (-180, 180))
      list.Add (ms)
  Next

End

Method OnRender( canvas:Canvas ) Override

  For Local ms:MovingSprite = Eachin list
      ms.sprite.Move (Sin (Degrees (Millisecs ())) * 0.1, Cos (Degrees (Millisecs ())) * 0.1, Sin (Degrees (Millisecs ())) * 0.1)
      ms.sprite.Alpha = Sin (Degrees (Millisecs () * 0.1))
  Next

  If Keyboard.KeyHit (Key.Escape) Then App.Terminate ()
  RequestRender()
  _scene.Update()
  _camera.Render( canvas )
  canvas.DrawText( "FPS="+App.FPS,0,0 )

End

End

Function Main()

New AppInstance

New MyWindow

App.Run() End

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#issuecomment-429656733, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3QvLF7IiBGBprOG2cLf50nRNCdIyZks5uk5XOgaJpZM4XbTCg .

DruggedBunny commented 5 years ago

Working great, thanks, Mark. Just updated my project if you want to see it. Particle effect needs some work still, but the sprites look to be working perfect.

I'll mess about and try getting global sprite materials working -- the ExplosionParticle uses a fixed array of 5 materials, but I think I ended up with one material per sprite in RocketParticle while fiddling with workarounds!

(I can't remember if I could change the colour of individual particles using just one material but think I'm doing some weird stuff at the moment anyway... )

Thanks again!

DruggedBunny commented 5 years ago

Remembered why I was creating a material per-sprite (on trying to re-implement reassigning each sprite's material, as it 'cools', from an array of five flame-colour materials, ie. White, Yellow, Orange, Red, Black):

ie. sprite.Material = MatArray [heat_level] ' MatArray:SpriteMaterial

(I think this may be the "related material bug" you were referring to?)

blitz-research commented 5 years ago

Actually, I was talking about the Mesh.CreateRect issue, which is fixed now.

Remembered why I was creating a material per-sprite (on trying to reassign each sprite's material as it 'cooled' from an array of five flame-colour materials, ie. White, Yellow, Orange, Red, Black):

If you are only using solid colors, it's still more efficient to use Entity.Color instead of a different material for each color.

On Mon, Oct 22, 2018 at 4:50 AM DruggedBunny notifications@github.com wrote:

Reopened #434 https://github.com/blitz-research/monkey2/issues/434.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#event-1916712558, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3Qpa2K_DiKSD6wDrV7ofyeNg_wmGFks5unJfNgaJpZM4XbTCg .

DruggedBunny commented 5 years ago

I'll delve in again tomorrow (and will try the quad fix, though I don't really need it now), but from memory, using a single SpriteMaterial and trying to change the colour affected all sprites at once -- I assumed Entity.Color was changing the colour of the single material. Will try again tomorrow...

Many thanks!

blitz-research commented 5 years ago

Using a single SpriteMaterial and trying to change the colour affected all sprites at once

Yes, this is correct, but I meant changing the Entity.Color. This only works if you're not using a texture though.

On Mon, Oct 22, 2018 at 11:44 AM DruggedBunny notifications@github.com wrote:

I'll delve in again tomorrow (and will try the quad fix, though I don't really need it now), but from memory, using a single SpriteMaterial and trying to change the colour affected all sprites at once -- I assumed Entity.Color was changing the colour of the single material. Will try again tomorrow...

Many thanks!

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#issuecomment-431710711, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3Qq_XJziB_6NidiB89IZkXrdSUY4Xks5unPjOgaJpZM4XbTCg .

DruggedBunny commented 5 years ago

OK, I'd assumed sprites'/entities' colours/alphas were controlled via a default material that I had to create.

However, there seem to be problems relating to creating sprites with no material, possibly relating to having a parent, too -- the example below crashes for me at _camera.Render. (Switch to the "FAILS" New Sprite line using no material -- left working here just for reference.)

Interestingly, in my game, I've updated my explosion particle code like this, and it doesn't crash, despite having no material!

            Local sprite:Sprite = New Sprite (rocket.RocketModel) ' Just a Model

                ' sprite.Parent             = Null

... but if I enable sprite.Parent = Null it crashes. The sprites are created with the rocket Model as parent for positioning, then 'freed' via parent = Null to operate independently under physics control.

(Interestingly, I get 'attempt to invoke method on null instance' in debug mode, but it doesn't highlight the line in Ted2Go.)

I can't reproduce this parenting part in my sample below!

Will upload the current rocket source if needed, but perhaps getting the sample below to work will just fix it.

Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..

Class MyWindow Extends Window

    Field _scene:Scene
    Field _camera:Camera
    Field _light:Light
    Field _ground:Model
    Field _sprite:Sprite

    Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

        Super.New( title,width,height,flags )
    End

    Method OnCreateWindow() Override

        'create (current) scene
        _scene=New Scene
        _scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
        _scene.AmbientLight = _scene.ClearColor * 0.25
        _scene.FogColor = _scene.ClearColor
        _scene.FogNear = 1.0
        _scene.FogFar = 200.0

        'create camera
        _camera=New Camera( Self )
        _camera.AddComponent<FlyBehaviour>()
        _camera.Move( 0,2.5,-5 )

        'create light
        _light=New Light
        _light.CastsShadow=True
        _light.Rotate( 45, 45, 0 )

        'create ground
        Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
        Local groundMaterial:=New PbrMaterial( Color.Lime )
        _ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
        _ground.CastsShadow=False

        Local spmat:SpriteMaterial = New SpriteMaterial ()

        ' FAILS:

'       _sprite = New Sprite (_camera)

        ' WORKS:

        _sprite = New Sprite (spmat, _camera)

        _sprite.Move (0, 0, 5)

        If _sprite = Null Then Print "Null" ' Fine

    End

    Method OnRender( canvas:Canvas ) Override

        Print "Requesting render..."
        RequestRender()
        Print "Updating scene..."
        _scene.Update()
        Print "Rendering scene..."              ' Boom AFTER this!
        _camera.Render( canvas )
        Print "Drawing text..."
        canvas.DrawText( "FPS="+App.FPS,0,0 )
        Print "OnRender complete"
    End

End

Function Main()

    New AppInstance

    New MyWindow

    App.Run()
End
blitz-research commented 5 years ago

Ok, fixed missing default material in develop.

On Tue, Oct 23, 2018 at 2:42 PM DruggedBunny notifications@github.com wrote:

OK, I'd assumed sprites'/entities' colours/alphas were controlled via a default material that I had to create.

However, there seem to be problems relating to creating sprites with no material, possibly relating to having a parent, too -- this crashes for me at _camera.Render if you switch to the "FAILS" New Sprite line with no material (left working line here just for reference).

Interestingly, in my game, I've updated my explosion particle code like this, and it doesn't crash, despite having no material!

      Local sprite:Sprite = New Sprite (rocket.RocketModel) ' Just a Model

' sprite.Parent = Null

... but if I enable sprite.Parent = Null it crashes. (Interestingly, I get 'attempt to invoke method on null instance' in debug mode, but it doesn't highlight the line in Ted2Go.)

I can't reproduce this parenting part in my sample below! The sprites are created with the rocket Model as parent for positioning, then 'freed' via parent = Null to operate independently under physics control.

Namespace myapp3d

Import ""

Import ""

Import ""

Using std.. Using mojo.. Using mojo3d..

Class MyWindow Extends Window

Field _scene:Scene Field _camera:Camera Field _light:Light Field _ground:Model Field _sprite:Sprite

Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

  Super.New( title,width,height,flags )

End

Method OnCreateWindow() Override

  'create (current) scene
  _scene=New Scene
  _scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
  _scene.AmbientLight = _scene.ClearColor * 0.25
  _scene.FogColor = _scene.ClearColor
  _scene.FogNear = 1.0
  _scene.FogFar = 200.0

  'create camera
  _camera=New Camera( Self )
  _camera.AddComponent<FlyBehaviour>()
  _camera.Move( 0,2.5,-5 )

  'create light
  _light=New Light
  _light.CastsShadow=True
  _light.Rotate( 45, 45, 0 )

  'create ground
  Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
  Local groundMaterial:=New PbrMaterial( Color.Lime )
  _ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
  _ground.CastsShadow=False

  Local spmat:SpriteMaterial = New SpriteMaterial ()

  ' FAILS:

' _sprite = New Sprite (_camera)

  ' WORKS:

  _sprite = New Sprite (spmat, _camera)

  _sprite.Move (0, 0, 5)

  If _sprite = Null Then Print "Null" ' Fine

End

Method OnRender( canvas:Canvas ) Override

  Print "Requesting render..."
  RequestRender()
  Print "Updating scene..."
  _scene.Update()
  Print "Rendering scene..."              ' Boom AFTER this!
  _camera.Render( canvas )
  Print "Drawing text..."
  canvas.DrawText( "FPS="+App.FPS,0,0 )
  Print "OnRender complete"

End

End

Function Main()

New AppInstance

New MyWindow

App.Run() End

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#issuecomment-432054239, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3QmEkBYBRXDcwFA5gB1twL3FQV1owks5unnPzgaJpZM4XbTCg .

DruggedBunny commented 5 years ago

Thanks, Mark... but there's something wrong with sprite colours now, when using default material!

It's like only colours with an element of red get shown (I think), and of those, the colours are weirdly stripped of something... here, for example, Color.Orange sprites are shown in magenta, under:

    Method OnRender( canvas:Canvas ) Override

        Local copy:Sprite = sprite.Copy ()

            copy.Color = Color.Orange' White

Color.Blue and Color.Green simply don't appear.

Demo below...

Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..

Class MyWindow Extends Window

    Field _scene:Scene
    Field _camera:Camera
    Field _light:Light

    Field sprite:Sprite

    Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

        Super.New( title,width,height,flags )
    End

    Method OnCreateWindow() Override

        'create (current) scene
        _scene=New Scene
        _scene.ClearColor = Color.Black
        _scene.AmbientLight = _scene.ClearColor * 0.25
        _scene.FogColor = _scene.ClearColor
        _scene.FogNear = 1.0
        _scene.FogFar = 200.0

        'create camera
        _camera=New Camera( Self )
        _camera.AddComponent<FlyBehaviour>()
        _camera.Move( 0,2.5,-5 )

        'create light
        _light=New Light
        _light.CastsShadow=True
        _light.Rotate( 45, 45, 0 )

        sprite = New Sprite ()

    End

    Method OnRender( canvas:Canvas ) Override

        Local copy:Sprite = sprite.Copy ()

            copy.Color = Color.Orange' White
'           Print copy.Color
            Local size:Float = Rnd (0.1, 2.0)
            copy.Scale = New Vec3f (size, size, 1.0)
            copy.Move (Rnd (-100.0, 100.0), Rnd (-100.0, 100.0), Rnd (50.0, 150.0))

        RequestRender()
        _scene.Update()
        _camera.Render( canvas )
        canvas.DrawText( "FPS="+App.FPS,0,0 )
    End

End

Function Main()

    New AppInstance

    New MyWindow

    App.Run()
End

Try Color.Rnd (), too -- it produces random RGBs (shown by Print), but only the sprites in a range best described as Barratts Fruit Salad gets shown!

blitz-research commented 5 years ago

Mmm, lollies look good.

Should be fixed now in develop - I messed up the new Color.ToRGBA stuff, this is always a bit trickier than it seems!

On Sun, Nov 11, 2018 at 7:22 AM DruggedBunny notifications@github.com wrote:

Thanks, Mark... but there's something wrong with sprite colours now, when using default material!

It's like only colours with an element of red get shown (I think), and of those, the colours are weirdly stripped of something (red??)... here, for example, Color.Orange sprites are shown in magenta, under:

Method OnRender( canvas:Canvas ) Override

  Local copy:Sprite = sprite.Copy ()

      copy.Color = Color.Orange' White

Demo below...

Namespace myapp3d

Import ""

Import ""

Import ""

Using std.. Using mojo.. Using mojo3d..

Class MyWindow Extends Window

Field _scene:Scene Field _camera:Camera Field _light:Light

Field sprite:Sprite

Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

  Super.New( title,width,height,flags )

End

Method OnCreateWindow() Override

  'create (current) scene
  _scene=New Scene
  _scene.ClearColor = Color.Black
  _scene.AmbientLight = _scene.ClearColor * 0.25
  _scene.FogColor = _scene.ClearColor
  _scene.FogNear = 1.0
  _scene.FogFar = 200.0

  'create camera
  _camera=New Camera( Self )
  _camera.AddComponent<FlyBehaviour>()
  _camera.Move( 0,2.5,-5 )

  'create light
  _light=New Light
  _light.CastsShadow=True
  _light.Rotate( 45, 45, 0 )

  sprite = New Sprite ()

End

Method OnRender( canvas:Canvas ) Override

  Local copy:Sprite = sprite.Copy ()

      copy.Color = Color.Orange' White

' Print copy.Color Local size:Float = Rnd (0.1, 2.0) copy.Scale = New Vec3f (size, size, 1.0) copy.Move (Rnd (-100.0, 100.0), Rnd (-100.0, 100.0), Rnd (50.0, 150.0))

  RequestRender()
  _scene.Update()
  _camera.Render( canvas )
  canvas.DrawText( "FPS="+App.FPS,0,0 )

End

End

Function Main()

New AppInstance

New MyWindow

App.Run() End

Try Color.Rnd (), too -- it produces random RGBs (shown by Print), but only the sprites in a range best described as Barratts Fruit Salad gets shown!

https://camo.githubusercontent.com/cab65a824e87578b812a81545021b537738b4e6b/687474703a2f2f636172742e6372616e6368732d737765657473686f702e636f2e756b2f696d616765732f70726f64756374732f66727569745f73616c61645f63686577732e6a7067

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#issuecomment-437605355, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3QtWTQU6L1X-S35QCPU2ksxTHwhuGks5utxlugaJpZM4XbTCg .

DruggedBunny commented 5 years ago

That's looking spot-on now with my rocket particles using default material -- thanks!

I did a little experiment, leaving a plain sprite (Copy'd from a master sprite) when deleting each particle, and with default material I can now hit 10,000 sprites leaving a cool 3D trail through the sky at 60 FPS. (You'll notice 52 fps here -- it's pretty much dead-on 10k when it starts to drop.)

EDIT: Latest update includes this stuff.

10ktrail

Couple of mostly-unrelated queries if you get chance...

1) While trying to make things framerate-independent, I think I've got the hang of OnUpdate's elapsed parameter, but for non-physics entities that I also want to move/rotate/fade out framerate-independently, I've thought that I could really use Scene's elapsed value -- could that be made accessible, or would it make no sense to use that outside of Behaviour's OnUpdate methods?

2) Totally unrelated: I noticed btCompoundShape had been started at some point, and I believe this is what I would need to stop my rocket rotating awkwardly about its (conical) base when landing -- the idea being to attach a cuboid shape (below the cone) whose corners fit the four fin positions, hence making it only tip in the four resulting directions. Just one for the wishlist! (It would also allow bolt-on rocket engines a-la Kerbal Space Program, quadcopter-drone simulation, etc.)

seyhajin commented 5 years ago

Can be closed.