On 15/10/2014 at 13:38, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 15
Platform: Windows ;
Language(s) : C++ ;
---------
Hi PluginCafe,
here I will try to summarize the object-oriented relations between:
* BaseObject
* RayObject
* PolygonObject (type: OPolygon)
* BaseObject (type: OSphere)
because they keep confusing me.
The documentation lacks a clear overview of such relations and my plugin might heavily rely on assumptions that could be wrong in practice which could lead to undefined behavior and bugs that are hard to nail down.
Please correct me anywhere when I am making wrong assumptions.
Imagine the following scene of a Null, which is the parent of a Cone, which is the parent of a Cube:
_<_img src="https://dl.dropboxusercontent.com/u/15216944/Objecthierarchyc4d.png" height="393" width="430" border="0" /_>_
Now I'm writing a VideoPostData plugin and in the Execute method I iterate over all RayObjects that are available in the VolumeData.
From my understanding each RayObject has a link, which seems to be NOT nullptr for Cube and Cone. The link is a BaseObject-pointer and is some sort of special. It has no parents and seems not to be in the "normal" hierarchy of objects. The GetUp() function, for example, returns a nullptr. When this is the case one can use GetCacheParent() which seems to return the "real" object in the hierarchy, visible in C4D. This BaseObject actually has parents etc. so that GetUp(), for example, returns a valid object. In our example it looks like this:
RayObject (Cube) has a link to a BaseObject (Cube) that is somewhat special which has a CacheParent (Cube) that is the object from the hierarchy which then has a "normal" parent Cone, which then has a parent Null.
I try to illustrate the relationship here:
Now I want to find a tag for a given RayObject. I'm interested in the "nearest" tag. So basically it should behave like the material system of C4D, that is: If an object has the tag of interest, get it and return it. If it does not have the specified tag, search upwards in the hierarchy until you find a tag of interest. When you find one, return it (in some sense, the object inherits the tag from one of its parents above). When we reach the top of the hierarchy without finding a tag, return nullptr.
Here is the code:
BaseTag* C4dHelper::findNearestTag(BaseObject* pBaseObject, Int32 tagId)
{
BaseObject* pCurrent = pBaseObject;
while (pCurrent != nullptr)
{
BaseTag* pBaseTag = pCurrent->GetTag(tagId);
if (pBaseTag != nullptr)
return pBaseTag;
if (pCurrent->GetUp() != nullptr)
pCurrent = pCurrent->GetUp();
else
pCurrent = pCurrent->GetCacheParent();
}
return nullptr;
}
This code works great, at least I think so, because all my knowledge is gathered by try-and-error.
When I want to do the same with a hierarchy that looks like this:
<_<_img src="https://dl.dropboxusercontent.com/u/15216944/Objecthierarchyc4d_sphere.png" height="304" width="321" border="0" /_>_" />
... everything seems to change because the sphere is of type O_SPHERE (in the RayObject) and of type Osphere (in the BaseObject). My guess is, that spheres can be handled extermely fast in a raytracer, so this might be an optimization for such objects. Therefore, no vertex, normal, uv buffers are created and the Object is not a PolygonObject, but some "other strange thing".
Again, here is an attempt to visualize the relationship:
So how would I retrieve the "nearest tag" now? Where can I find a connection between a RayObject (that is a sphere) and its "real" object in the hierarchy?
What I am additionally doing is accessing the polygon-buffers for vertices, normals and uv-coordinates from the "linked" BaseObjects. So I do not extract the buffers from the RayObject, because I had problems working with the RayPolygons. My code that extracts the vertex, index, normal and uv-buffers from a PolygonObject works great so far, so I just fed it the RayObject->link and it worked.
But how would I extract those buffers from a sphere?
My hacky attempt would be this:
1. handle all RayObjects of type O_POLYGON as I described above
2. don't handle RayObject of type O_SPHERE, O_SKY and O_FLOOR at all
3. go through the scene hierarchy and test all objects for the type OSphere
4. Create copies of the BaseObjects that have type OSphere and convert them to editable objects
5. The spheres are now PolygonObjects and can be processed as always
This approach just doesn't feel right. Has anyone a better solution?
I have the strong feeling, that I am doing something really wrong, or that I have misunderstood very important concepts in C4D.
And if you have read this far, you could even provide me with hints of extracting tangents as well
Thank you all for your time, this post might take some time to respond to^^