Page MenuHome

BGE : addObject in python without reference object.
ClosedPublic

Authored by Porteries Tristan (panzergame) on Apr 5 2015, 8:25 PM.

Details

Summary

Making the reference argument optional for the addObject function.

scene.addObject("Cube")

This allows to keep the rotation, scale and position of the original object.
To avoid layer problems with lights if the reference arguments is None, the new object have the same layer than the active layers in scene.

Diff Detail

Repository
rB Blender

Event Timeline

Porteries Tristan (panzergame) retitled this revision from to BGE : addObject in python without reference object..
Porteries Tristan (panzergame) updated this object.

Just a little inline comment on the documentation.

Could you attach a blend file that demonstrates the new functionality? It'll be needed for the release log anyway.

doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
145–146

The code seems to not only use the center (which I read as "center position"), but also orientation & scale of the referenced object. The parameter name suggests that other should be a vector ("the object's center") whereas it actually should be an object itself. Maybe change this to "The object which position, orientation, and scale to copy". Might as well clarify this when you're adding stuff anyway.

Porteries Tristan (panzergame) edited edge metadata.

Fix documentation, keep original position, orientation and scale of the dupli object if those arguments are not set.

only make reference argument optional

If the other argument can be omitted, I'd rather see it as an optional argument.

We looked at that yesterday, @Porteries Tristan (panzergame) is working on it. There is still an issue with the layer number, as newly added layers are moved to the reference object's layer. Without such a reference object, this move cannot happen. For lights this is not a big issue, as light objects expose the layer property. @Porteries Tristan (panzergame) is investigating exposing that same property for KX_GameObject too, comparing it to adding a layer argument to the addObject method.

I moved layer attribute from KX_Light to KX_GameObject for avoid problems with shadow renders, But for that i have needed to make SetLayer virtual in KX_Light.

source/gameengine/Ketsji/KX_GameObject.cpp
2478 ↗(On Diff #3928)

I'm a big fan of keeping error checking and error handling close to each other. Right now they are on opposite sides of the method. Using if (!PyLong_Check(value)) instead, you can swap the error-handling and normal-handling cases, increasing readability.

2480 ↗(On Diff #3928)

No more check on a max value of 20?

I'm also wondering if we should keep accepting out-of-range values. It's more Pythonic to throw a ValueError exception instead. As per the Zen of Python: "Errors should never pass silently. Unless explicitly silenced."

source/gameengine/Ketsji/KX_Scene.cpp
951

What does this do exactly? You may want to add a comment that explains why this is a good fallback value.

2502

Style: spaces around operators.

As disused on IRC moving the get/set attribute to KX_GameObject is not needed. You only need the changes from KX_GameObject.h and /KX_Scene.cpp.

source/gameengine/Ketsji/KX_GameObject.cpp
2476 ↗(On Diff #3928)

Asterix in front of self not after KX_GameObject. KX_GameObject *self =

2493 ↗(On Diff #3928)

KX_GameObject *self =

source/gameengine/Ketsji/KX_Light.h
63

If the get/setter code is not moved from KX_LightObject to KX_GameObject, change this to virtual is not necessary.

source/gameengine/Ketsji/KX_Scene.cpp
843

Why this code I s removed?

2510–2511

Unnecessary tab after If ( and unnecessary space between the last two parenthesis.

source/gameengine/Ketsji/KX_GameObject.cpp
2480 ↗(On Diff #3928)

The old check is stupid because layers are a mix of power of 2.
So layer 5 : (1 << 5) = 32, but the old layer check doesn't accept a value greater than 20 so we can't use more than 4 layers.

source/gameengine/Ketsji/KX_Scene.cpp
843

Because i think that it's useless to cast the gameobject if we just need to make SetLayer virtual.

Porteries Tristan (panzergame) edited edge metadata.

Fix typo, better layer check.

source/gameengine/Ketsji/KX_GameObject.cpp
2480 ↗(On Diff #3928)

I agree that the old < 20 check was stupid ;-)

source/gameengine/Ketsji/KX_Light.h
63

Being able to set a light's layer has little use, when you can't set the objects' layers too.

Thomas Szepe (hg1) requested changes to this revision.Apr 12 2015, 8:07 PM
Thomas Szepe (hg1) edited edge metadata.

To clarify, as I told Tristan multiple times on IRC and described in my last comment moving the API call to KX_GameObject is not necessary. I told him also that I have tested it and it was working without this changes.
I also described in my last comment what is only necessary to get it work.

As disused on IRC moving the get/set attribute to KX_GameObject is not needed. You only need the changes from KX_GameObject.h and /KX_Scene.cpp.

There are no reaction, no discussion, no good explanation why this changes are absolutely necessary. I feel me like Don Quichotte which was fighting against windmills.

Here Is my patch and my test file.


So please tell me what is the difference to your patch.

This revision now requires changes to proceed.Apr 12 2015, 8:07 PM

I'm actually in favour of Tristan's patch.

One advantage of making KX_GameObject::setLayer() virtual, is that we no longer need this kind of code:

(*git)->SetLayer(groupobj->GetLayer());
// If the object was a light, we need to update it's RAS_LightObject as well
if ((*git)->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
{
    KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
    lightobj->SetLayer(groupobj->GetLayer());
}

where (*git) is a KX_GameObject *. The code doesn't use the virtual language feature that C++ offers us, yet tries to implement the functionality of virtual by itself, and only for a specific subclass. This pattern occurs twice in KX_Scene. IMO, this is crazy enough to actually start using the virtual keyword, as the current situation just adds code bloat and confusion. To me it's hard to see what's to lose by improving this situation.

Furthermore, it's nice to be able to set which layer is lit by a lamp, but what is use is that when you can't move the objects that are actually supposed to be lit to that layer? If that is not what we're aiming at, then I wonder why there is a KX_GameObject::setLayer() method at all.

Porteries Tristan (panzergame) edited edge metadata.

Leave layer getter and setter in light as well as for wrong layer check.

@Sybren A. Stüvel (sybren)

One advantage of making KX_GameObject::setLayer() virtual, is that we no longer need this kind of code:

(*git)->SetLayer(groupobj->GetLayer());
// If the object was a light, we need to update it's RAS_LightObject as well
if ((*git)->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
{
    KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
    lightobj->SetLayer(groupobj->GetLayer());
}

Did you looked into my patch? Because I also made exactly this changes. I removed this code and changed KX_GameObject::setLayer() to virtual.

I digged not much into the lighting code, so maybe I am wrong. But as far I have seen KX_GameObject::setLayer() is used to store the object layer which is later compared with the light layer to define wich object has to be light by this light. So we only need to set this layer with KX_GameObject::setLayer() only for mesh objets that could be light. For Lights we only need to set the layer in the Lightobject with KX_LightObject::setLayer(). Sure we can set the KX_GameObject::setLayer() to, but I think actually it is not necessary, because a light can't be light and for the moment we don't have an API wich returns the actual object layer.

If you want to set the object light layer to, then this should be done in an extra patch, because the new "addObject in python without reference object" feature patch has nothing to with this changes.

Also the wrong layer check should be done in an extra patch.

source/gameengine/Ketsji/KX_Light.h
63

Maybe I missed something. But as I described in my previous inline comment, I think change this to virtuel is not necessary. There is no derivation of KX_LightObject class.
Did you have any issues if this method not virtual?

source/gameengine/Ketsji/KX_Light.h
63

Children function have to be virtual to call KX_GameObject::SetLayer (line 111 KX_Light.cpp) to update the layer in the RAS_LightObject and in the KX_GameObject.

Thomas Szepe (hg1) edited edge metadata.

Looks OK for me.

source/gameengine/Ketsji/KX_Light.h
63

Tristan what you clam her is not correct. KX_GameObject::SetLayer(layer); in line 111 will work without setting SetLayer in KX_Light.h to virtual.
If you don't be leave me then put a printout in every SetLayer method.

printf(" KX_LightObject::SetLayer %i\n", m_lightobj->m_layer);
printf(" KX_GameObject::SetLayer %i\n", m_layer);

The keyword virtual is only necessary in the base class. There is no need to use it for the method in the inherent class. It would be only necessary if there would be also an inherent class of KX_Light.

I don't think that Linux compiler are working that different to the Microsoft Visual C++.

But if you want you can leave the virtual in KX_Light.h. I don't care about it. Some people some only don't know which one of the methods the have to make virtual so the make every method virtual. And some people also use virtual in inherit class only for documentation reason. I don't know what Campbell prefer. I don't find any related in the code style guide.

I only wanted to inform you that this change is not necessary. You can leave it if you want.

This revision is now accepted and ready to land.Apr 14 2015, 8:25 PM
Sybren A. Stüvel (sybren) requested changes to this revision.Apr 20 2015, 4:53 AM
Sybren A. Stüvel (sybren) edited edge metadata.
This comment was removed by Sybren A. Stüvel (sybren).
This revision now requires changes to proceed.Apr 20 2015, 4:53 AM
Sybren A. Stüvel (sybren) edited edge metadata.

(ignore my last comment)

This revision is now accepted and ready to land.Apr 20 2015, 4:54 AM
This revision was automatically updated to reflect the committed changes.

No offense to @Sybren A. Stüvel (sybren) or @Thomas Szepe (hg1), but I'm a little concerned that this was committed without a review from @Campbell Barton (campbellbarton), @Dalai Felinto (dfelinto), @Daniel Stokes (kupoman), @Benoit Bolsee (ben2610) or myself. While the patch overall looks okay (thanks to feedback from reviewers), there can be subtle details which newer devs might not notice. On the other hand, this patch has been in the tracker for almost a month and I didn't get around to reviewing it, so I'm glad things are at least moving along.

doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
146

This is documented strangely. First off, you might want to put reference=None in the method signature to denote that it is optional. Also, the English is a little strange. It would read better as:

"if the object to add is a light and there is no reference, the light's layer will be the same as the active layer in the blender scene."

source/gameengine/Ketsji/KX_Scene.cpp
952

This does not seem like the correct behavior. Can we not get the layer off of the Blender Object instead of the Scene? I can imagine someone using layers to control what gets lit by certain lights, and then having all the lighting be "wrong" if addObject is used without a reference. Even though the feature would be working as the author intended, it would still end up as a bug in our tracker.

source/gameengine/Ketsji/KX_Scene.cpp
952

No we can't use the Blender Object layer, because as default the Blender Object layer is inactive.

Moguri. Your comment comes a little bit late. Against Campbell's rules we only need two reviewers for new features as long it don't touch Blenders core http://lists.blender.org/pipermail/bf-gamedev/2015-February/000486.html.
I didn't know that you want to review this patch. Because there are some patches out there which are waiting since years for your review (example 7 Aug 2013 T36388 --> D1205), so I thought you don't will review this.
You were also assigned as reviewer since 5 April. Also there where six days between Sybrens OK and you don't gave any comment or added other reviewers to it.
I think that should be enough time to write a little sentence like "Please old on, I want to review this first" or add Campbell as reviewer. If you would have done this, I would have waited with the commit.
I also don't want always to add Campbell as review for such simple patches. But if it is OK for him to add him to every patch, I will do this in future.

Actually I am not intended to wait longer then one or max two weeks, after we get two accepts.