UseSelfAsParent makes spawner move twice as fast.

I think I found a bug or at least something very unintuitive that you should warn about everywhere. :)

I have made these observations when using svn revision 2787 in a very clean minimal setup both in the program, only one object is created from config, and in the ini where only one object includes one spawner.

If I activate UseSelfAsParent on a spawner and then set a position for the object that includes the spawner the object is drawn in the right position but the spawner get moved two times. I hope I don't sound like a fool but that was not what I had expected. :side:
[MainObject]
Position = (150, 0, 0)
Spawner = Spawner
Graphic = ParticleGraphic
Color = (255,0,0)

[Spawner]
Object = SpawnerObject
WaveSize = 1
UseSelfAsParent = true

[SpawnerObject]
Speed = (0, 150, 0)
Graphic = ParticleGraphic
Color = (0, 0, 255)

[ParticleGraphic]
Texture = Particle.png

Comments

  • edited February 2012
    Hi!

    I'm not sure what you mean by "was moved two times" but yeah, that doesn't sound like an intended behavior. :)
    I'll check that tomorrow night (I was sick all day today).
  • edited February 2012
    I just guess that's whats happening, if we change position to Speed another way to phrase it is that the spawned objects moves twice as fast.
  • jimjim
    edited February 2012
    Hey iarwain, hope you get well soon.
  • edited February 2012
    Yea get well soon. I'm trying to look into this but it is confusing. =) The problem above is only true if the SpawnerObject has a body but it was not completely clear when I used Position instead of Speed. This also effects Rotation in a strange way and seems to counteract it making the Spawner always spawn in the same direction even when the MainObject and thous the spawner rotate.
  • edited February 2012
    Getting better, thanks! =)
    At least today I'm at work.

    Yeah, that really sounds strange and I'll check tonight.
  • edited February 2012
    So, bug it was!

    A little bit of history now.

    For a long time orx would issue error messages when someone was trying to add a physics body to an object which was part of a hierarchy.
    For a very simple reason: Box2D doesn't have a single clue about orx's object world hierarchy.
    What should happen when the hierarchy said to move somewhere while the physics simulation tells us to go somewhere else?
    So I tried to find a compromise and undertook something that quickly became one of the most annoying and head scratching piece of code I had to write for orx. Especially because we also support per-object time distortion and I wanted it to blend smoothly with the whole system.
    And apparently I didn't update correctly speeds for objects in a hierarchy whose parents are transferring scale and/or rotation to their children. That should be fixed now. Hopefully. :)

    Now I have a question to ask.

    Do you really need that mix of body + hierarchy? What is your goal exactly?
    There might be a better way to achieve what you need (like using joints, for example, which didn't exist back when I implemented that hybrid system).

    Anyway, if you sync the svn, let me know if things behave better for you.
  • edited February 2012
    My plan is to use something like this...
    [Players]
    ChildList = AlgoJerViA
    
    [AlgoJerViA]
    ChildList = ThePod#Engine0#Weapon1
    
    [Engine0@CommonEngine]
    Position = @ThePod.Engine2Position
    Scale =	0.25
    StartPaused = true
    
    [Weapon1@CommonCannon]
    Position = @ThePod.Weapon1Position
    Scale =	0.5
    StartPaused = false
    
    [ThePod] ;===================================
    Graphic	= ThePodGraphic
    Body = ThePodBody
    Engine0Position		=	(-96, 77, 0.6)
    Weapon0Position		=	(-101, -8, -0.6)
    
    [CommonEngine]
    Spawner	= CommonEngineSpawner
    
    [CommonEngineSpawner]
    Object = CommonEngineObject
    WaveSize = 1
    WaveDelay = 0.3
    UseSelfAsParent	= true
    
    [CommonEngineObject]
    Speed = (0, 150, 0)
    LifeTime = 3
    Graphic = CommonEngineParticleGraphic
    Body = CommonEngineParticleBody
    
    

    I want to make a spaceship in config and specifies engine and weapons positions but then let the player choose what to put in those places.
    Do you really need that mix of body + hierarchy?/quote]

    I'm not sure I know what that means exactly. I want both the engines and the weapons to have bodies, the engines is mainly a extra effect so that flames are deflected of objects. For weapons it is meant simply keep track of who is shooting what and when and to make some bouncing against shields or asteroids.

    I want the spawners to adapt to the overridden position and to the spaceships rotation so that I only have to specify engine fire direction on one axis.

    UseSelfAsParent and adding the spaceships speed to the objects seems like a nice way of doing things.
  • edited February 2012
    AlgoJerViA wrote:
    I want to make a spaceship in config and specifies engine and weapons positions but then let the player choose what to put in those places.

    Sounds good to me.
    I'm not sure I know what that means exactly. I want both the engines and the weapons to have bodies, the engines is mainly a extra effect so that flames are deflected of objects. For weapons it is meant simply keep track of who is shooting what and when and to make some bouncing against shields or asteroids.

    I want the spawners to adapt to the overridden position and to the spaceships rotation so that I only have to specify engine fire direction on one axis.

    UseSelfAsParent and adding the spaceships speed to the objects seems like a nice way of doing things.

    Mmh, I think that's that part I don't understand.

    If you have a hierarchy of objects, here you have a parent which is your ship and children: engine, weapons, body.

    The children will always follow the parent as they're defined in its space. You can either do that by using the property ChildList on the parent or by setting orxObject_SetParent() on the engine/weapons/body when creating them.

    Now for the spawners that are attached to weapons and engine. Those actually are children to weapons/engine and will remain attached no matter what.

    The property UseSelfAsParent concerns the spawned objects (ie. weapon projectiles and engine fire particles). If you set this to true, that means that the projectiles/particles will be set as children of the spawners and will then move with them.

    That sounds weird to me as wherever your ship is going, the particles will be dragged around instead of continuing their original course in space: ie. they are linked to the spawner. If the ship rotates, the engine and its spawner will rotate around the ship pivot and so will the fire particles, which will generate a weird effect.

    If you simply want to know who emitted them, you can call orxObject_GetOwner() (the spawner owns the emitted objects).

    That's why I wanted to know what you were trying to achieve, as UseSelfAsParent is only useful for very limited situations. I can't even think of one as an example right now. :)
  • edited February 2012
    As you can see I had set speed in the object that would be spawned. I don't know if that's on intention or not but in that case the speed vector won't be rotated, I now know that I could use ObjectSpeed on the spawner and then set UseRelativeSpeed to true. On top on that something else happens on a related mater. I want my engines and weapons to be fired from inside the ships graphic but anyway collide with themselves and with the spaceship again when they once has left the graphic. That has been very tricky to implement, I experimented with both check flags and set solid but nothing works perfectly so far. In the current version the spaceship has flag 0x1 and the engine has 0x2, spaceships check mask is 0xFFFFF and engines mask is 0xFFFFE and is then set to 0xFFFFF on first contact remove, that doesn't work very well but introduces the problem I have now. If the particle body from the engine is set to be relative large it will collide with another particle and the check mask will be change when it still is inside the spaceship... and here comes the interesting part, when the particle collides inside the spaceship it will in some manner move the spaceship and/or the spawned object so the spaceship will make a short instant jump but in that jump it forgets it's engines spawner that will be displaced. Al objects will continue to behave as expected expect that the position value is offset. I don't know if that might be a bug or if it is so that a colliding body inside a colliding body is undefined and it is me that are using orx in the wrong way.

    I have been confused about GetOwner() and GetParent() and the spooky frame hierarchy :woohoo: for a while to the point that I currently store pointers to parents in objects userdata :S but your advice to use GetOwner in this situation got a reference to orientated around so I think it cleared up pretty well.

    Have you made any progress on the debugview mode?
  • edited February 2012
    Ah, welcome to the fabulous world of game physics engine and Box2D in particular.
    That being said, Box2D is far from being the worse in that matter, on thebcontrary, it's just that game physics simulation are kind of unpredictable by nature.

    I believe that it's the "...and the spaceship again" part that is giving you troubles?

    So, first of all, unless you want bouncing projectiles, I'd set them as Solid = false, otherwise Box2D will process the collisions beforehand and apply new velocities on both objects based on forces transfer. Hence your jumpy ship and the unpredictability that follows (yes I don't think that inside object collisions are very well handled if at all).
    Before reactivating the flags on your projectiles, you can check with objects/parts are getting separated and only doing it when it's a projectile/ship separation that occurs.

    And even if you want your engine particles to bounce of the ships/walls/etc, I'd still set them as Solid=false and, upon new contact, modify their speed myself, based on their current speed and the collision normal. This way the ship will continue its trajectory unaffected.

    Lastly, if engine particles collision are just eye candies and not part of the gameplay, I'd focus on getting the physics to work for the gameplay elements first, and when that's done I'd come back on particles for some polish. :)

    Ah yes, the GetOwner/GetParent is a bit confusing. Especially when using something as ChildList that will set both properties. :)

    PS: the physics debug should be finished tonight. :)
  • edited February 2012
    orxSTATUS orxFASTCALL StandAlone::PhysicsEventHandler( const orxEVENT* currentEvent )
    {
    orxOBJECT* hRecipient = orxOBJECT(currentEvent->hRecipient);
    orxOBJECT* hSender = orxOBJECT(currentEvent->hSender);

    orxOBJECT* hRecipientParent = orxOBJECT( orxObject_GetOwner( hRecipient ) );
    orxOBJECT* hSenderParent = orxOBJECT( orxObject_GetOwner( hSender ) );
    ...

    Assuming hRecipient is the spawned object then hRecipientParent is always null even when it works for the other colliding object. That is another think that drove me towards UseSelfAsParent however it doesn't work anyway.
  • edited February 2012
    The owner of a spawned object is a spawner, not an object.
    The owner of that spawner is an object.

    Here if you want the engine object from an engine particle, it'd be:
    orxOBJECT *pstEngine = orxOBJECT(orxSpawner_GetOwner(orxSPAWNER(orxObject_GetOwner(pstEngineParticle))));
    
  • edited February 2012
    [Player]
    ChildList = SpaceShip#Engine
    
    [Engine@EngineSpawner]
    Position = (0, 100, 0)
    
    [SpaceShip]
    Body = Abody
    
    [EngineSpawner]
    Spawner = Aspawner
    


    I had it like this and then the owner became EngineSpawner that is not in turn owned by anything, I had expected the owner of the spawned particles to be Engine. Also in this configuration when I apply force I have to do it on the SpaceShip since it is the only object with a body, that will move the SpaceShip object but that does not effect the parent, it feels like every solution I can come up with will defeat the purpose of having object orientation.
  • edited February 2012
    A spawner has to be owner of the spawned objects, that's how it can track of the currently active object number and delete them when the CleanOnDelete property is set to true.

    You could change the owner manually when receiving the spawn event, but that would break both theses features. If you don't need them I guess it's ok.

    If your parent isn't your main body, you should consider using a joint to link the different parts together instead.

    This way applying any force/impulse/torque to a sub-body will be propagated to the full compound.
Sign In or Register to comment.