VolumeData Class Overview? [SOLVED]

On 09/09/2014 at 14:01, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R13 
Platform:   Windows  ;   
Language(s) :     C++  ;

I have not used the VolumeData class very much. And I don't really understand in what context where are supposed to use it in (tool plugins, videoPostdata plugins, etc...)?
I'm not really sure how to use it in general.

Here is an example using the VD class in a CommandData plugin.
But some of the functions don't work. And I'm thinking that's because I'm using it in the wrong kind of plugin.

Bool SimplePlugin::Execute(BaseDocument *doc)  
  //This code block works  
  VolumeData *vd = VolumeData::Alloc();  
  BaseDraw *bd = doc->GetRenderBaseDraw();  
  BaseObject *camera = bd?bd->GetSceneCamera(doc) :NULL; //Gets the active camera and assigns it to the variable "camera"  
  RenderData *rdata = doc->GetActiveRenderData();       //Gets the render settings  
  LONG x = 0;  
  LONG y = 0;  
  Ray ray;  
  Vector campos = camera->GetAbsPos();  
  GePrint(RealToString(ray.v.x)+String(" ")+RealToString(ray.v.y)+String(" ")+RealToString(ray.v.z));//Prints the rotation value of the active camera  
  GePrint(RealToString(vd->CameraToScreen(campos).y));                                               //Prints the active camera's y screen position  
  //This code does not work  
  LONG objCount = vd->GetObjCount();  
  GePrint(LongToString(objCount));         //<---Always returns 0  :-{   
  RayObject *rayObj = vd->GetObj(1);  
  BaseObject *obj = (BaseObject * )rayObj;  //Crashes!  
  return TRUE;  

What if I wanted to use the GetObj() method. What kind of plugin do I use for that to work?
What is all the ray stuff in that class for? Camera rays, Rendering rays?


On 10/09/2014 at 01:54, xxxxxxxx wrote:

Hi Scott,

the VolumeData class is really only used in everything that belongs to rendering. It is the render structure containing all the final render data, for example objects are converted to polygons etc (however, not normal PolygonObjects but RayObjects...it is most probably an optimised version of a PolygonObject calls that is advantageous during the renderers ray casting (and most probably less memory intensive)).

So whenever there is a rendering (either material preview or normal rendering) this structure is generated and filled by Cinema 4D(!). Then you can also access all parameters. This is the case in all the ShaderData, MaterialData, VideoPostData where you get the already filled VolumeData structure passed automatically.

If you create your own VolumeData and fill it with AttachVolumeDataFake, it will only have some data available (the docs state which these are). RayObjects are not filled though and also the more complex structures are not filled but you can access stuff like conversions (as you made above with CameraToScreen) and work with the generated ray for that camera (useful if you want to do your own ray casting, or even write an own renderer, custom shadow maps etc..can be used for many things).

Hope that helps

On 10/09/2014 at 07:57, xxxxxxxx wrote:

Thanks Katachi. That does help clear it up a little bit.
I noticed that most of the VD code on this forum is used in shader & material plugins. So I wasn't really sure why people were talking about it in the context of getting objects and ray casting. And I didn't understand how rendering had anything to do with grabbing scene objects.
But from your explanation it sounds like it does some sort of inventory process before rending the scene.

I still don't understand the ray part though.
There's different types of rays (GetRayEnvironment, GetRaySky, GetRayForeground, GetRay).
Are these rays being sent to the camera?
What exactly are these rays?
I don't have a good handle on what these rays are and what they're doing.


On 10/09/2014 at 08:29, xxxxxxxx wrote:

Ray part: There is actually only one that deals with the ray and that is GetRay(). This one gives you the ray (so the line that expands from the passed pixel position to infinity in view direction).

Note that GetRayEnvironment and the other two give you a RayObject! That's because these are special objects that have infinite extent so a ray does not hit them really (they have no geometry). That way you can handle them separately.

On 10/09/2014 at 08:38, xxxxxxxx wrote:

Does the ray that shoots out from the pixels always shoot towards the camera?
Or does the ray shoot out from the pixels in scene space like polygon normals?

In other words.
If I use GetRay() does that set up a relationship between the camera and a specific pixel?

On 10/09/2014 at 08:51, xxxxxxxx wrote:

Ray myray;
vd->GetRay(x, y,&ray);

This will generate a ray for the pixel coordinate (x,y).
The ray direction is always away from the camera (from the pixel into the scene....into your screen).

On 10/09/2014 at 09:03, xxxxxxxx wrote:

Ok. So we have these rays shooting out from pixels into the scene(I'm still foggy on this concept).
I'm assuming the X&Y pixels are the coordinates of the image that's rendered to the screen?
So that means that the higher the resolution setting, the more rays are shot into the scene?

I'm trying to understand how this is useful?
Is this for calculating things like light bounces?

On 10/09/2014 at 09:46, xxxxxxxx wrote:

this is calculating the whole image 🙂
to render, you are doing an integration over camera lens

so you shot 1 ray/pixel per iteration, this ray hits something "an object, environment, light"
once it hits it reacts, if it hits an object it can bounce again!! (not sure if this is supported here, but this is how render engine works"

where the ray hits, you can read texture, UV, normal, polygon, any custom thing that you may want "like sculpting, or most modelling tools that interact with mouse, it depends on rays to get the pick point and then an algorithm depending on movement of mouse and point of picking"

On 10/09/2014 at 11:10, xxxxxxxx wrote:

OK. I think I've got it now.
As usual. The name they gave this class is horribly confusing.
It should have been called "SceneData"...not "VolumeData".

I ran some tests using one of the SDK VideoPostData examples. And it's making a lot more sense to me now.

    //Create an instance of the Volume Data class  
  VolumeData *vd = vps->vd;  
  //Get the number of objects in the scene  
  LONG count = vd->GetObjCount();  
  //Get the first object in the OM  
  //Then convert it from a RayObject type to a BaseObject type  
  RayObject *rObj = vd->GetObj(0);  
  BaseObject *obj = rObj->link;  
  //This code gets a specific vertice in the object  
  //This also works if the object is a primitive..Very handy!!  
  Vector *points = rObj->padr;  
  GePrint( RealToString(points[0].x) + " " + RealToString(points[0].y) + " " + RealToString(points[0].z) );  
  //Create a ray in these x&y screen coords.  
  //Note the vector value when rendering in the perspective, right,left, top, bottom views  
  //The vector results are similar to a polygon normals vector. This can help determine where the camera is pointing  
  Ray ray;  
  LONG x = 200;  
  LONG y = 200;  
  GePrint(RealToString(ray.v.x) + " " +RealToString(ray.v.y) + " " + RealToString(ray.v.z));

Thanks for the help guys.