Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
I am writing an object to draw a cube. I draw each polygon by using DrawPolygon() to draw it. I did not use DrawBox() to draw because I don't know how to set the length of the side. When I use DrawPolygon() to draw, the shadow of the cube is wrong, how to set its shadow.
DrawPolygon()
DrawBox()
DRAWRESULT Box_Obj::Draw(BaseObject *op, DRAWPASS drawpass, BaseDraw *bd, BaseDrawHelp *bh) { if (drawpass == DRAWPASS::OBJECT) { if (op == nullptr || bd == nullptr) { return DRAWRESULT::FAILURE; } GeData Ge_Date; //Get side length information from parameters. op->GetParameter(RIGID_SHAPE_SIZE_X, Ge_Date, DESCFLAGS_GET::NONE); Float rigid_size_x = Ge_Date.GetFloat(); op->GetParameter(RIGID_SHAPE_SIZE_Y, Ge_Date, DESCFLAGS_GET::NONE); Float rigid_size_y = Ge_Date.GetFloat(); op->GetParameter(RIGID_SHAPE_SIZE_Z, Ge_Date, DESCFLAGS_GET::NONE); Float rigid_size_z = Ge_Date.GetFloat(); op->GetParameter(RIGID_GROUP_ID, Ge_Date, DESCFLAGS_GET::NONE); //Set the drawing matrix to world coordinates. bd->SetMatrix_Matrix(nullptr, Matrix()); //Get object coordinates. Vector pos = op->GetAbsPos(); bd->SetLightList(BDRAW_SETLIGHTLIST_NOLIGHTS); bd->SetTransparency(127); Vector Box_vc[4] = {Vector(0)}; Vector Box_vp0[4] = { Vector(pos.x + rigid_size_x, pos.y + rigid_size_y, pos.z + rigid_size_z), Vector(pos.x + rigid_size_x, pos.y + rigid_size_y, pos.z - rigid_size_z), Vector(pos.x + rigid_size_x, pos.y - rigid_size_y, pos.z - rigid_size_z), Vector(pos.x + rigid_size_x, pos.y - rigid_size_y, pos.z + rigid_size_z), }; Vector Box_vp1[4] = { Vector(pos.x + rigid_size_x, pos.y + rigid_size_y, pos.z + rigid_size_z), Vector(pos.x + rigid_size_x, pos.y + rigid_size_y, pos.z - rigid_size_z), Vector(pos.x - rigid_size_x, pos.y + rigid_size_y, pos.z - rigid_size_z), Vector(pos.x - rigid_size_x, pos.y + rigid_size_y, pos.z + rigid_size_z), }; Vector Box_vp2[4] = { Vector(pos.x + rigid_size_x, pos.y + rigid_size_y, pos.z + rigid_size_z), Vector(pos.x + rigid_size_x, pos.y - rigid_size_y, pos.z + rigid_size_z), Vector(pos.x - rigid_size_x, pos.y - rigid_size_y, pos.z + rigid_size_z), Vector(pos.x - rigid_size_x, pos.y + rigid_size_y, pos.z + rigid_size_z), }; Vector Box_vp3[4] = { Vector(pos.x - rigid_size_x, pos.y + rigid_size_y, pos.z + rigid_size_z), Vector(pos.x - rigid_size_x, pos.y + rigid_size_y, pos.z - rigid_size_z), Vector(pos.x - rigid_size_x, pos.y - rigid_size_y, pos.z - rigid_size_z), Vector(pos.x - rigid_size_x, pos.y - rigid_size_y, pos.z + rigid_size_z), }; Vector Box_vp4[4] = { Vector(pos.x + rigid_size_x, pos.y - rigid_size_y, pos.z + rigid_size_z), Vector(pos.x + rigid_size_x, pos.y - rigid_size_y, pos.z - rigid_size_z), Vector(pos.x - rigid_size_x, pos.y - rigid_size_y, pos.z - rigid_size_z), Vector(pos.x - rigid_size_x, pos.y - rigid_size_y, pos.z + rigid_size_z), }; Vector Box_vp5[4] = { Vector(pos.x + rigid_size_x, pos.y + rigid_size_y, pos.z - rigid_size_z), Vector(pos.x + rigid_size_x, pos.y - rigid_size_y, pos.z - rigid_size_z), Vector(pos.x - rigid_size_x, pos.y - rigid_size_y, pos.z - rigid_size_z), Vector(pos.x - rigid_size_x, pos.y + rigid_size_y, pos.z - rigid_size_z), }; bd->DrawPolygon(Box_vp0, Box_vc, true); bd->DrawPolygon(Box_vp1, Box_vc, true); bd->DrawPolygon(Box_vp2, Box_vc, true); bd->DrawPolygon(Box_vp3, Box_vc, true); bd->DrawPolygon(Box_vp4, Box_vc, true); bd->DrawPolygon(Box_vp5, Box_vc, true); } return SUPER::Draw(op, drawpass, bd, bh); }
Thank, AiMiDi
Hello @aimidi,
thank you for reaching out to us. Please excuse the delay, but your questions had to be reassigned internally, which is why I only took it on yesterday.
The main reason for your problems is the incomplete initialization of Vector Box_vc[4] = {Vector(0)};. Box_vc should be initialized with four vectors as you do declare yourself. This partial initialization causes the shading errors you did experience.
Vector Box_vc[4] = {Vector(0)};
Box_vc
Please also note that you did flag your posting as R21, which is out of the support cycle. Below I do provide some example code written for S24. It should work on R21, since there have been no changes to the involved interfaces and methods as far as I am aware of, but I did not try to compile the code for R21. The code is also narrative in nature and lines out a few other problems with the code provided by you. I hope this will be helpful to you.
R21
S24
Cheers, Ferdinand
The result:
The code:
// Example for some drawing operations via ObjectData::Draw(). // // Draws a white polygon and a red cube in the local coordinate system of the BaseObject. The main // problem of your code was that you did not initialize the color array properly. // // As discussed in: // https://plugincafe.maxon.net/topic/13441 #include "c4d.h" #include "c4d_symbols.h" class Pc13441 : public ObjectData { INSTANCEOF(Pc13441, ObjectData) public: static NodeData* Alloc() { return NewObjClear(Pc13441); } DRAWRESULT Draw(BaseObject* op, DRAWPASS drawpass, BaseDraw* bd, BaseDrawHelp* bh) { if (drawpass == DRAWPASS::OBJECT) { if (op == nullptr || bd == nullptr) { return DRAWRESULT::FAILURE; } // Set the drawing matrix to the global matrix of the object we are drawing for. This is // more intuitive than what you did, because we can now just draw as if the origin of // our object is the origin of the drawing space and also will respect the orientation // of the that object. Or in short: We will draw in the local matrix of op. bd->SetMatrix_Matrix(nullptr, op->GetMg()); // The replacement for the drawing size parameter(s) of your example. Vector poylgonSize = Vector(100); // We are now going to draw a manually shaded polygon. This will ignore shading defined // by the user/scene. The user turning on and off shadows in the viewport or moving // lights will have no impact on this. // Define the vertices of the polygon to draw. Vector vertices[4] = { Vector(+poylgonSize.x, +poylgonSize.y, 0), Vector(-poylgonSize.x, +poylgonSize.y, 0), Vector(-poylgonSize.x, -poylgonSize.y, 0), Vector(+poylgonSize.x, -poylgonSize.y, 0) }; // Define the color for each vertex to draw, Cinema will interpolate between these // colors. Vector colors[4] = { Vector(1), Vector(1), Vector(1), Vector(1) }; // You did not initialize this array properly and also did pass in black as a color. // So, this, // // Vector colors[4] = { Vector(0) }; // // where we only initialize the 0th element, is not equivalent to that: // // Vector colors[4] = { Vector(0), Vector(0), Vector(0), Vector(0) }; // // The first one will give you the weird shading errors you had while the latter will // give you an all black polygon. Black as a color is of course not that useful if we // want to see some shading. // If our polygon is a quad or triangle. bool isQuad = true; // Set the drawing transparency to about 50%. bd->SetTransparency(127); // Draw the polygon. bd->DrawPolygon(vertices, colors, isQuad); // Now we are going to draw a box. // The size of the box. float boxSize = 50; // A transform for the box, we are going to draw it a bit off-center, so that it does // not overlap with the polygon we did draw. Matrix boxTransform = Matrix(); boxTransform.off = Vector(200, 0, 0); // The color for the box, this can only be a solid color. Vector boxColor = Vector(1, 0, 0); // And if we want to draw it as a wire frame. bool isWireFrame = false; // Draw the box. bd->DrawBox(boxTransform, boxSize, boxColor, isWireFrame); // For more complex drawing operations one could use DrawPoly() to draw a single // polygon, while respecting scene shading, or DrawPolygonObject() to draw a BaseObject // that is a PolygonObject. Which will also respect user defined scene shading by // default. I would not recommend constructing such polygon object to draw in Draw() as // this method is rather performance critical. If possible, this should be done // beforehand, i.e., in a cached manner. } return SUPER::Draw(op, drawpass, bd, bh); } };
Can someone help me, I don't know what to do?