Lales.Charles Posted August 31, 2020 Posted August 31, 2020 Dear Unigine team, I'm currently trying to setup properly an HC transporting a cargo: H/C > hook > rope > bag SDK 2.12, Physics::setEnabled(1); HC can be moving on predefined trajectory, on key pressed or from CIGI remote ctrl. User can change cone model as rope length pressing + - keys. In object tree, the hook is associated to SlingComponent managing different 3D cones and the rope system as bellow described. #### SlingComponent.h #### #pragma once #include <UnigineComponentSystem.h> #ifdef DLL_EXPORT #define DLLEI __declspec(dllexport) #else #define DLLEI __declspec(dllimport) #endif using namespace Unigine; class DLLEI SlingComponent : public Unigine::ComponentBase { public: COMPONENT(SlingComponent, Unigine::ComponentBase); COMPONENT_INIT(init); COMPONENT_UPDATE(update); COMPONENT_SHUTDOWN(shutdown); void init(); void update(); void shutdown(); PROP_NAME("SlingComponent"); //ig_config.xml described how bellow params are exposed to CIGI PROP_PARAM(Float, cable_length, 20, "Cable length"); PROP_PARAM(Float, bag_weight, 100, "Bag weight"); private: Vector<NodePtr> cable_cones; //ObjectMeshStaticPtr int cone_idx = 0; ObjectDummyPtr hook; ObjectMeshDynamicPtr rope; ObjectMeshDynamicPtr bag; void parameter_changed(PropertyPtr property, int num); }; #### SlingComponent.cpp #### #include "SlingComponent.h" #include <UnigineApp.h> #include <UnigineLog.h> #include <UnigineNode.h> #include <UnigineConsole.h> #include <UniginePrimitives.h> using namespace Unigine; #include "../Util.h" using namespace Math; REGISTER_COMPONENT(SlingComponent) /// function, creating a named rope with specified parameters at pos ObjectMeshDynamicPtr createBodyRope(char* name, float radius, float length, int segments, int slices, const Mat4& tm) { // creating a cylinder dynamic mesh ObjectMeshDynamicPtr OMD = Primitives::createCylinder(radius, length, segments, slices); // setting parameters OMD->setWorldTransform(tm); OMD->setMaterial("CableMaterial", "*"); //OMD->setMaterialParameterFloat4("albedo_color", vec4(0.5f, 0.5f, 0.0f, 1.0f), 0); OMD->setName(name); //assigning a rope body to the dynamic mesh object and setting rope parameters BodyRopePtr body = BodyRope::create(OMD); body->setMass(1.0f); body->setRadius(0.05f); body->setFriction(0.5f); body->setRestitution(0.05f); body->setRigidity(0.05f); body->setLinearStretch(0.0001f); return OMD; } /// function, creating a named dummy body of a specified size at pos ObjectDummyPtr createBodyDummy(char* name, const vec3& size, const Vec3& pos) { // creating a dummy object ObjectDummyPtr OMD = ObjectDummy::create(); // setting parameters OMD->setWorldTransform(Mat4(translate(pos))); OMD->setName(name); //assigning a dummy body to the dummy object and adding a box shape to it BodyDummy::create(OMD); OMD->getBody()->addShape(ShapeBox::create(size)/*, translate(0.2f, 0.2f, 0.2f)*/); return OMD; } ObjectMeshDynamicPtr createBodyBag(char* name, const vec3& size, const Vec3& pos) { // creating a cylinder dynamic mesh ObjectMeshDynamicPtr OMD = Primitives::createBox(size); // setting parameters OMD->setWorldTransform(Mat4(translate(pos))); OMD->setMaterial("mesh_base", "*"); //OMD->setMaterialParameterFloat4("albedo_color", vec4(0.5f, 0.5f, 0.0f, 1.0f), 0); //OMD->setCollision(1,0); OMD->setName(name); //assigning a box body to the dynamic mesh object and setting box parameters auto body = BodyRigid::create(OMD); body->addShape(ShapeBox::create(size), translate(vec3(0.0f))); //body->setMass(10.0f); OMD->getBody()->getShape(0)->setMass(100.0f); return OMD; } void SlingComponent::init() { Log::message("SlingComponent init from root node %s\n ", node->getRootNode()->getName()); Util::find_nodes_in_children(node, Node::OBJECT_MESH_STATIC, "cone", &cable_cones); getProperty()->addCallback( Property::CALLBACK_PARAMETER_CHANGED, MakeCallback(this, &SlingComponent::parameter_changed)); } void SlingComponent::update() { bool modelUp = false, modelDown = false; if (!Console::isActive()) { modelUp = (App::clearKeyState('+') == 1); modelDown = (App::clearKeyState('-') == 1); } if (modelUp || modelDown) { if (modelUp && cone_idx < cable_cones.size()) //-> over means no mesh display, let user check fps impact cone_idx++; if (modelDown && cone_idx > -1) //-> under means no mesh display, let user check fps impact cone_idx--; for (int i = 0; i < cable_cones.size(); i++) cable_cones[i]->setEnabled(i == cone_idx); if (modelUp) cable_length = cable_length + 10.f; else if (modelDown) cable_length = cable_length - 10.f; } else {}//NTD } void SlingComponent::shutdown() { Log::message("SlingComponent shutdown from root node %s\n", node->getRootNode()->getName()); } void SlingComponent::parameter_changed(PropertyPtr property, int num) { if (cable_length.getID() == num) { auto value = property->getParameterPtr(num)->getValueFloat(); Log::message("parameter_changed node %s cable length %f\n", node->getName(), value); //remove if already exists if (hook && rope && bag) { node->removeChild(hook); hook->deleteForce(); rope->deleteForce(); bag->deleteForce(); } //add const float hlength = cable_length.get(); //< horizontal length of the cable const float radius = 0.15 / 2.; //< radius of the cable const int slices = 10; //< nb of slices of the cable (higher=rounder) const int segments = min(100, max(10, int(hlength / 5))); // number of segments in the cable (min 10, max 100) hook = createBodyDummy("slingHook", vec3(0.05f, 0.05f, 0.05f), Vec3::ZERO); rope = createBodyRope("slingRope", radius, hlength, segments, slices, Mat4(translate(0.0f, 0.0f, -hlength / 2))); bag = createBodyBag("slingBag", vec3(1.f, 1.f, 1.f), Vec3(0.0f, 0.0f, -hlength)); JointParticles::create(hook->getBody(), rope->getBody(), hook->getPosition(), vec3(0.55f)); JointParticles::create(bag->getBody(), rope->getBody(), bag->getPosition(), vec3(0.55f)); node->addChild(hook); } else if (bag_weight.getID() == num) { bag->getBody()->getShape(0)->setMass(bag_weight.get()); } } The result is already interesting.. but still not satisfying / realistic: - I can't get proper init position for the bag, seem to be at origin whereas it should be at the end of the rope - How to set proper elasticity? Should be nearly none, even if the bag mass can reach 1 tonne - Is it better way to set up everything? -- Hook is the only child of HC -- Between rope and bag, it is JointParticles instead of JointBall Kind regards, Charles
Lales.Charles Posted September 2, 2020 Author Posted September 2, 2020 Dear Unigine team, Any feedback? Support would be appreciated on this ;-) Kind regards, Charles
morbid Posted September 2, 2020 Posted September 2, 2020 Hi Charles, sorry for the silence. We're still looking into this. Will answer by the end of the week, earlier if possible. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
Lales.Charles Posted September 3, 2020 Author Posted September 3, 2020 Hi, So, sorry but I still don't get it working properly.. Let's consider simpler system, with a bag fixed onto a hook under the HC: HC is a node sling is a node with SlingComponent associated from SlingComponent method (init, update or paramChanged), I do node->addChild(hook); hook is ObjectDummyPtr bag is ObjectMeshDynamicPtr both are joint with JointFixed So, in bellow code, what am I doing wrong? Even with fixed HC in world, I can't get right init position and stable system... is it normal? auto transform = node->getWorldTransform(); // hc > sling auto hook = createBodyDummy("slingHook", vec3(0.05f, 0.05f, 0.05f), transform * Mat4(translate(0.0f, 0.0f, -1.f))); auto bag = createBodyBag("slingBag", vec3(1.f, 1.f, 1.f), transform * Mat4(translate(0.0f, 0.0f, -10.f))); if (hook && bag) { auto jf = JointFixed::create(hook->getBody(), bag->getBody(), Vec3(0.0f, 0.0f, -10.0f)); jf->setNumIterations(10); node->addChild(hook); } with ObjectDummyPtr createBodyDummy(char* name, const vec3& size, const Mat4& transform) { // creating a dummy object ObjectDummyPtr OMD = ObjectDummy::create(); // setting parameters OMD->setWorldTransform(transform); OMD->setName(name); //assigning a dummy body to the dummy object and adding a box shape to it BodyDummy::create(OMD); OMD->getBody()->addShape(ShapeBox::create(size), translate(0.0f, 0.0f, 0.0f)); return OMD; } ObjectMeshDynamicPtr createBodyBag(char* name, const vec3& size, const Mat4& transform) { // creating a cylinder dynamic mesh ObjectMeshDynamicPtr OMD = Primitives::createBox(size); // setting parameters OMD->setWorldTransform(transform); OMD->setMaterial("mesh_base", "*"); OMD->setName(name); //assigning a box body to the dynamic mesh object and setting box parameters auto body = BodyRigid::create(OMD); body->addShape(ShapeBox::create(size), translate(vec3(0.0f))); OMD->getBody()->getShape(0)->setMass(100.0f); return OMD; } Kind regards, Charles
Lales.Charles Posted September 8, 2020 Author Posted September 8, 2020 Hi, Any feedback? First post is 1 week ago, and still blocked on it.. At least previous post simplified setup... what am I doing wrong? Kind regards, Charles
morbid Posted September 8, 2020 Posted September 8, 2020 Hi Charles, We're sorry it takes too long. Rope setup isn't that easy and my colleague keeps experimenting to find a better behavior. I believe he'll answer you by tomorrow. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
Lales.Charles Posted September 8, 2020 Author Posted September 8, 2020 Hi, Ok, thanks for investigating. What about the easier (easiest) setup: HC is a node sling is a node with SlingComponent associated from SlingComponent method (init, update or paramChanged), I do node->addChild(hook); hook is ObjectDummyPtr bag is ObjectMeshDynamicPtr both are joint with JointFixed I don't get the bag fixed at proper position -10m under the H/C... it is properly init, but after that start to orbit with weird trajectory :-o Kind regards, Charles
alexander Posted September 10, 2020 Posted September 10, 2020 Hi Charles, I don't get the bag fixed at proper position -10m under the H/C... it is properly init, but after that start to orbit with weird trajectory I tried to reproduce this. I saw a problem with the correct position. But I didn't see the "weird trajectory" movement. It's fixed in my case. I created a new world, added a NodeDummy with the component, placed it at (0, 0, 12). Your code was added to a init() method. About the proper position: Instead of this: node->addChild(hook); use this: node->addWorldChild(hook). What's the difference? - addWorldChild() doesn't move your new child in the world (it recalculates the local transform, the world transform would be the same as before). - addChild() does nothing with the local transform, it's the same as before, but as a result, world transform changes (objects change their position relative to the new parent). So, in your sample you change the hook's position right after creating the fixed joint. About the weird trajectory... Maybe it's a side effect of addChild(), maybe there are surface collisions with scaled objects, maybe the reason is in the physics settings... Who knows. Can you send your project if the problem is not the addChild()? Between rope and bag, it is JointParticles instead of JointBall. I think you can't create a realistic sling rope (with dynamic length) by using BodyRope / JointParticles. It can be done via JointBalls at the moment. How to set proper elasticity? Should be nearly none, even if the bag mass can reach 1 tonne. In case of JointBalls increase both joint's number of iterations and restitution. I've finally made a sample and attached it to this post. Just create a new C++ project (double precision, SDK 2.12.0.2) and apply to it files from the attach. Run the "sling_rope" world. Controls:J and L - rotate the craneI and K - increase or decrease length of the rope API gives you possibility to attach or detach the bag. In this sample the rope is a set of BodyRigids + ShapeCapsules + JointBalls. It can collide with the world, dynamically generate its mesh with corrected uv, can change its length during runtime. Is this what you are trying to achieve? Best regards, Alexander sling_rope.zip
Lales.Charles Posted September 11, 2020 Author Posted September 11, 2020 Hi, Thanks a lot for this dedicated and clear sample! To change in RT rope length is really cool. Still adapting it to our context, little difference / difficulties already: Crane is actually moving since it is helicopters Attache / detach bag requires add/removeChild or world version.. right? otherwise (with moving crane) you don't get independent falling trajectory.. Bag doesn't have any mass here, only rope segment, already with 100Kg I get some weird behaviour (kept your join params) With geodetic pivot, is there any special setWorldPosition to perform at init? Kind regards, Charles
alexander Posted September 13, 2020 Posted September 13, 2020 Hello Charles, Attache / detach bag requires add/removeChild or world version.. right? otherwise (with moving crane) you don't get independent falling trajectory.. Don't use add/removeChild between helicopters and bags. Physical relationship should only be built through physical joints. Node hierarchy should be "flat". The bag should never be a child to the helicopter. Bag doesn't have any mass here, only rope segment, already with 100Kg I get some weird behaviour (kept your join params) In my sample the bag weights 10Kg (BodyRigid -> ShapeBox -> Mass): Try to increase iterations and softness (a little bit), but decrease restitution (a little bit) in the SlingRope component. With geodetic pivot, is there any special setWorldPosition to perform at init? No, everything should work fine. Best regards, Alexander
Lales.Charles Posted September 14, 2020 Author Posted September 14, 2020 Hi, Thanks, fixes make sens, and it starts to work fine. For the mass, have you tried with 100kg? 1 tone? 10kg is fine, rope is stable and nice. Already with 100kg the rope is dislocated.. To prospect on rope params, is there a way to use script in editor with physic activated maybe? Geodetic pivot itself is maybe not the issue, but CIGI init seems to disturb a bit... Here is init with fix HC in world with geodetic pivot -> nice (with 10kg bag...) Here is same world, with HC loaded from CIGI. The HC is red circle on the right, whereas the bag is on the left. Detach / attach bag not helping, change rop length same thing. Kind regards, Charles
alexander Posted September 14, 2020 Posted September 14, 2020 For the mass, have you tried with 100kg? 1 tone? 10kg is fine, rope is stable and nice. Already with 100kg the rope is dislocated.. Because maximum value of the joint's restitution is 1, all you can do is to increase "Segment Mass" value. If your bag weights 100kg then use 2.5kg as the "segment mass". If your bag weights 1000kg, use 25kg.To prospect on rope params, is there a way to use script in editor with physic activated maybe? Only if you rewrite SlingRope.cpp to UnigineScript. ;-)Here is same world, with HC loaded from CIGI.Is HC a entity? Helicopter and HC are different entities? Is the Bag an entity? I think I don't undestrand what exactly is going on in this case. Best regards, Alexander
Lales.Charles Posted September 14, 2020 Author Posted September 14, 2020 Hi, Sorry, HC is helicopter. The bag is simply a node of the loaded world, as you explain. Works fine if HC is loaded directly in the world as well, but face some issue if it is loaded from CIGI. Bellow you can see the hook (or crane in your code) is just under the HC loaded / moving with CIGI.. But the rope is somehow stuck at the origin, and segment are build only between bag and this origin. Otherwise bag / segment masses seem to work, thanks! Kind regards, Charles
cash-metall Posted September 16, 2020 Posted September 16, 2020 Hi! there are several problems 1. in AppWorldLogic::init() enable physics int AppWorldLogic::init() { // init systems, do some optimizations for IG Game::setEnabled(1); Physics::setEnabled(1); // switch on Render::setMotionBlur(0); Render::setLightsLensFlares(0); //.... } 2. when you create an entity by CIGI, you need the colision detection enable to always be on (in EntityControl packet) 3. entity creating in 0.0.0 and the length of the rope is calculated immediately (in SlingRope::init). you need recalculate rope length again when you picking up weight. For example: rope_component->setLength(static_cast<float>(length(rope_component->bag_node->getWorldPosition() - rope_component->getNode()->getWorldPosition()))); Thanks!
Lales.Charles Posted October 6, 2020 Author Posted October 6, 2020 Hi, Back on this issue, I thank you for your support but regret it is not working properly. Well, it is OK with:- Fix entity - Entity moving on spline predefined trajectory (AH-sling-spline.avi) - Entity controlled by CIGI HE (AH-sling-cigihe.avi) But the real case we try to deal with is KO: - Entity controlled by CIGI emitted by in-house playing flight data record (200ms) (AH-sling-replay-fdr.avi) Here is setup used to smooth trajectory when receiving CIGI ig_manager->setInterpolation(1); // enable interpolation and extrapolation ig_manager->setInterpolationPeriod(0.2); // s, default value is 0.04 ig_manager->setExtrapolationPeriod(0.2); // s, default value is 0.04, at least 1 step time, or n steps Would you see anything still to try? Kind regards, Charles AH-sling-cigihe.avi AH-sling-replay-fdr.avi AH-sling-spline.avi
alexander Posted October 7, 2020 Posted October 7, 2020 Hi Charles, Try to increase the rope segment mass. Something like x10. Something has changed? And, just in case, try to increase interpolation period to 0.4. Best regards, Alexander
Lales.Charles Posted October 8, 2020 Author Posted October 8, 2020 Hi, By default: Then CIGI exposed properties: But.. even checking different params, I can't get smthg reliable :-/ AH-sling-masses.avi Question: mutli-threading in UNG is possible / used with physic right? Would it change smthg? How can I activate it? Kind regards, Charles
silent Posted October 8, 2020 Posted October 8, 2020 Physics is multi-threaded by default. Since 2.12 you have no other options (no single-threaded physics anymore). How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
Recommended Posts