Thanks for your answer, it solved my problem.
I used: Vector::ClampMax()
and Vector::ClampMin()
to limit the tangent to the value I want.
Thank,
AiMiDi
Thanks for your answer, it solved my problem.
I used: Vector::ClampMax()
and Vector::ClampMin()
to limit the tangent to the value I want.
Thank,
AiMiDi
Hi everybody. I find when edit a interior scene or a huge map, it is hard to navigate through only mouse. The best way to control the camera is like FPS games or UE4.
There was vitual walkthrough in cinema 4d however it performs laggy and it's not a flying camera,then it was removed.
My friend write a plugin which make camera read keyboard, however it can only move along the world axis. Besides, it moves about 5 times per sec, laggy too. If anybody knows how to correctly do it, pls tell me thanks.
I used to take in game footage with a xbox controller, find it works perfectly.
So if a combine gamepad and real time keying(cappuccino in c4d), animating camera would be much easier.
These 2 videos demonstrates real time keying with mouse and keyboard to make camera movement and mechanical animations.
But with a gamepad, we can even achieve this level of control inside the soft ware. Follow character movement, focus on the face, camera shake you name it.
3D Connexion SpaceMouse can navigate like a gamepad, but not everybody afford that, and using 1 stick simultaneously to move and rotate is not that accurate.
If you knows how to get the right API, pls leave a comment. That would be really appriciated!
Hi @m_adam , thanks for your apply. I have solved this problem. The reason is I used maxon::BaseArray
to store tree node data. When I append the array, the address of node may change, but the next pointer in node remain unchanged. And this cause the crash.
I'm going to set a tree view as shown below. After adding items into the tree view for several times, it suddenly crashed in DrawText. This issue happens stably.
struct MyItem
{
enum
{
MATERIAL,
MESH,
CAMERA,
LIGTH
};
enum
{
OK,
WARNING,
ERROR
};
Int32 state = OK;
Int32 type = MATERIAL;
BaseList2D* element;
String parameter;
String problem;
};
struct MyItem
{
Int32 state = OK;
Int32 type = MATERIAL;
BaseList2D* element;
String parameter;
String problem;
};
struct MyItemNode
{
MyItem item; //data
MyItemNode* down = nullptr;
MyItemNode* next = nullptr;
};
using MyItemArray = maxon::BaseArray<MyItemNode>;
class MyTreeViewFunctions final : public TreeViewFunctions
{
void* m_selected_node = nullptr;
public:
static MyTreeViewFunctions& GetFunction()
{
static MyTreeViewFunctions func;
return func;
}
void* GetFirst(void* root, void* userdata) override
{
return static_cast<MyItemArray*>(root)->GetFirst();
}
void* GetDown(void* root, void* userdata, void* obj) override
{
return nullptr;
}
void* GetNext(void* root, void* userdata, void* obj) override
{
if (const auto node = static_cast<MyItemNode*>(obj))
return node->next;
return nullptr;
}
Bool IsSelected(void* root, void* userdata, void* obj) override
{
return m_selected_node == obj;
}
Int32 GetLineHeight(void* root, void* userdata, void* obj, Int32 col, GeUserArea* area) override
{
return 20;
}
Int32 GetColumnWidth(void* root, void* userdata, void* obj, Int32 col, GeUserArea* area) override
{
return 65;
}
void DrawCell(void* root, void* userdata, void* obj, const Int32 col, DrawInfo* drawinfo, const GeData& bgColor) override
{
if(!obj)
return;
const auto& item = static_cast<MyItemNode*>(obj)->item;
switch (col)
{
case MyDialog::LIST_COL_TYPE:
{
BaseBitmap* bm = nullptr;
switch (item.type)
{
case MyItem::MATERIAL:
bm = m_material_bitmap;
break;
case MyItem::MESH:
bm = m_mesh_bitmap;
break;
case MyItem::CAMERA:
bm = m_camera_bitmap;
break;
case MyItem::LIGTH:
bm = m_light_bitmap;
break;
default:;
}
drawinfo->frame->DrawBitmap(bm, drawinfo->xpos + drawinfo->width / 4, drawinfo->ypos + 2, ICON_SIZE, ICON_SIZE, 0, 0, bm->GetBw(), bm->GetBh(), BMP_NORMALSCALED);
break;
}
case MyDialog::LIST_COL_ELEMENT:
{
if (item.type == MyItem::MATERIAL)
{
if (auto* mat = reinterpret_cast<BaseMaterial*>(item.element); mat)
{
if (BaseBitmap* bm = mat->GetPreview(0); bm)
{
drawinfo->frame->DrawBitmap(bm, drawinfo->xpos, drawinfo->ypos + 2, ICON_SIZE, ICON_SIZE, 0, 0, bm->GetBw(), bm->GetBh(), BMP_NORMALSCALED);
}
}
}
drawinfo->frame->DrawSetTextCol(IsSelected(root, userdata, obj) ? COLOR_TEXT_SELECTED : COLOR_TEXT, COLOR_TRANS);
drawinfo->frame->DrawText(item.GetName(), drawinfo->xpos + ICON_SIZE + 2,drawinfo->ypos + drawinfo->height / 2, DRAWTEXT_VALIGN_CENTER);
break;
}
case MyDialog::LIST_COL_PARAMETER:
{
drawinfo->frame->DrawSetTextCol(IsSelected(root, userdata, obj) ? COLOR_TEXT_SELECTED : COLOR_TEXT, COLOR_TRANS);
drawinfo->frame->DrawText(item.parameter, drawinfo->xpos + 2,
drawinfo->ypos + (drawinfo->height - drawinfo->frame->DrawGetFontHeight()) / 2 + 2);
break;
}
case MyDialog::LIST_COL_PROBLEM:
{
drawinfo->frame->DrawSetTextCol(IsSelected(root, userdata, obj) ? COLOR_TEXT_SELECTED : COLOR_TEXT, COLOR_TRANS);
drawinfo->frame->DrawText(item.problem, drawinfo->xpos + 2, drawinfo->ypos + drawinfo->height / 2, DRAWTEXT_VALIGN_CENTER);
break;
}
default:;
}
}
Bool IsOpened(void* root, void* userdata, void* obj) override
{
return true;
}
String GetName(void* root, void* userdata, void* obj) override
{
return {};
}
Int GetId(void* root, void* userdata, void* obj) override
{
return 0;
}
Int32 GetDragType(void* root, void* userdata, void* obj) override
{
return NOTOK;
}
void Select(void* root, void* userdata, void* obj, Int32 mode) override
{
if(mode == SELECTION_SUB)
m_selected_node = nullptr;
else
m_selected_node = obj;
}
};
@kbar and @m_magalhaes, Thank you for your reply.
I know that parameter changes can be determined by overriding SetDParameter()
.
But I don't know how to override SetDParameter()
to know whether the user has added / deleted keyframes, or changed the value of keyframes (whether the small button next to the parameter is pressed). Thank you again for your help.
Thank,
AiMiD
As I demonstrated above, how to track the user's changes to the parameter animation in a custom ObjectPlugin
, or receive a message when the user changes the animation. Do I need to listen to the above events in ObjectData::Message()
?Can someone help me?
Thank,
AiMiD
@ferdinand Thank you for your reply.
My plugin is written in C++. Is there a way to call redshift.GetRSMaterialNodeMaster()
in C++ 's existing sdk? (or call the python code through C++)
Thank,
AiMiD
I need to get the node information on the Redshift material for a plugin that automatically adds maps, reads maps, and converts Redshift materials to default materials.
I don't know how to get the XPresso stored on the Redshift material. Can someone help me?
Thank,
AiMiD
I use ZipFile::CopyInFileInZip()
to compress the file into a zip package. However, when the file name contains non ASCII characters, the file name is replaced with an underscore. Is there a way to use non ASCII file names in zip without using external libraries?
AutoAlloc<ZipFile> zf;
if (zf == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
if (!zf->Open(fnZip, false, ZIP_APPEND_CREATE))
return maxon::UnknownError(MAXON_SOURCE_LOCATION);
Filename fnCopy;
while (fnCopy.FileSelect(FILESELECTTYPE::ANYTHING, FILESELECT::LOAD, "Select file to add to Zip File"_s))
{
zf->CopyInFileInZip(fnCopy, "textures/" + fnCopy.GetFileString());
}
Thank,
AiMiDi
@m_magalhaes Thank you for your advice.
Is the dynamics engine in Cinema4D called in a thread?
How does it update the location of the object?
Can you provide a general reference for my project?
Thank,
AiMiDi
@ferdinand @fwilleke80 Thank you for your reply.
I'm writing an IPR (Interactive Photorealistic Rendering) rendering plugin like octane
or redshift
. I need to send scene polygons and materials to the outside through IPC (Inter-Process Communication).
BaseDocument.Polygonize()
solved my problem very well.
I need further optimization, and I need to check whether the scene (tags, objects, et cetera) has been changed.
Does BaseDocument.Polygonize()
copy the Dirty
and HDirty
of the object?
Thank,
AiMiDi
@m_magalhaes Thank you for your reply, I'm sorry I didn't make it clear.
I wanted to create my own implementation of Bullet Engine. Because the dynamic systems of MMD and Cinema4D are different, the transformation is complicated.
I need to do is:
stepSimulation()
to let the engine world update.Thank,
AiMiDi