sevas55 Posted November 5 Posted November 5 (edited) По примеру отсюда создаю в коде несколько сфер, которые по физике притягиваются в некоторую точку (демо работы трубки осциллографа) При создании сферы функция OMD.SetCollision(false, 0) почему-то не отключает коллизию и сферы сталкиваются между собой, а мне столкновения не нужны. https://youtu.be/uwDZNJbXqHc Подскажите где я ошибся? Вот мой код, в сцену надо добавить Dummy с именем CathodeDummy и в настройках мира нужно обнулить гравитацию Spoiler using System.Collections; using System.Collections.Generic; using Unigine; [Component(PropertyGuid = "cf1779da44f5db9b596a72d5b9691824fb28b657")] public class Oscilloscope : Component { List<BodyRigid> ElectronList = new List<BodyRigid>(); int ElectronCount = 10; Node NodeCathodeDummy = World.GetNodeByName("CathodeDummy"); BodyRigid CreateElectron() { ObjectMeshDynamic OMD = Primitives.CreateSphere(0.05f, 12, 12); // OMD.Transform = MathLib.Translate(0.0f, 0.0f, 1.0f); OMD.SetCollision(false, 0); OMD.SetMaterialParameterFloat4("albedo_color", new vec4(255, 255, 0, 1.0f), 0); BodyRigid br = new BodyRigid(OMD); br.AddShape(new ShapeSphere(0.1f)); OMD.Body.GetShape(0).Mass = 1f; return br; } void Init() { for (int i = 0; i < ElectronCount; i++) { BodyRigid el = CreateElectron(); ElectronList.Add(el); } for (int i = 0; i < ElectronCount; i++) { float x,y,z; float forceMax = 2f; x = MathLib.RandFloat(-forceMax,forceMax); y = MathLib.RandFloat(-forceMax,forceMax); z = MathLib.RandFloat(-forceMax,forceMax); // vec3 x = MathLib.RandVec3((-1)*vec3.ONE, 1*vec3.ONE); ElectronList[i].AddWorldForce(vec3.ZERO, new vec3(x,y,z)); } Visualizer.Enabled = true; } void Update() { float Attr1X=0.5f, Attr1Y=1, Attr1Z=1; vec3 Attr1Pos = new vec3(Attr1X, Attr1Y, Attr1Z);//координаты 1го ускорителя Visualizer.RenderVector(vec3.ZERO,Attr1Pos,vec4.RED); for (int i = 0; i < ElectronList.Count; i++) { //притяжение к ускорителю 1 vec3 VecDist2Attract1 = (vec3)(Attr1Pos - ElectronList[i].Position);//векторное расстояние float Dist2Attract1 = VecDist2Attract1.Length2;//линейное расстояние float ForceAttr1 = 1/(Dist2Attract1+0.1f);//закон тяготения ElectronList[i].AddWorldForce(ElectronList[i].Position, ForceAttr1*VecDist2Attract1.Normalized); // Visualizer.RenderVector(ElectronList[i].Position,0.1*VecDist2Attract1,vec4.GREEN,0.1f); double d = MathLib.Distance2 (ElectronList[i].Position, vec3.ZERO); if (d > 20 ) { float x=0,y=0,z=0; //возврат электрона в нить накала z = MathLib.RandFloat(0, 0.5f); ElectronList[i].Position = new vec3(0,0,z); //после возврата снова добавляем толчок электрону чтобы он улетел float forceMax = 0.5f; x = MathLib.RandFloat(-forceMax,forceMax); y = MathLib.RandFloat(-forceMax,forceMax); z = MathLib.RandFloat(-forceMax,forceMax); vec3 forceEmission = new vec3(x,y,z); // ElectronList[i].AddWorldForce(vec3.ZERO, forceEmission); // Log.Message("{0}"+'\n', VecDist2Attract1); } } } } Заранее спасибо Edited November 5 by sevas55
sevas55 Posted November 6 Author Posted November 6 (edited) Прикрепляю готовый проект (605 МБ) Edited November 6 by sevas55
mifril Posted November 6 Posted November 6 Здравствуйте! Пока сразу на что обратил внимание. Вы создаете для объектов физическое тело(BodyRigid), а метод SetCollision вызываете у самого объекта, этот метод нужен когда у объекта нет физического тела оно статично находится в сцене но мы хотим, чтобы физичные объекты получали информацию о коллизиях с ними. Но когда у объекта есть физическое тело настройки коллизий у поверхностей не учитываются. Попробуйте выставлять в параметры шейпа который добавляете в тело маску Exclusion. Например setExclusionMask(1). https://developer.unigine.com/en/docs/future/principles/physics/collision/ - задесь можно прочитать о том что я хотел объяснить, если Вы не доконца поняли о чем я говорю. 1
sevas55 Posted November 6 Author Posted November 6 Добавил OMD.Body.GetShape(0).ExclusionMask = 1; Теперь объекты не сталкиваются между собой. Подскажите, как решить задачу правильно, я сделал как смог, но не уверен, что оптимально с точки зрения эффективности кода. Мне принципиально иметь возможность применять к объекту силу функцией AddWorldForce, чтобы движок сам просчитывал их движение, учитывая массу и было похоже на симуляцию движения в гравитационном поле. Но также важно чтобы объекты не сталкивались между собой. Код не прошу, хотя бы тезисно: создаем RigidBody=> и так далее. Благодарю за помощь.
mifril Posted November 7 Posted November 7 Здравствуйте! Я так понимаю, что задача решена и Вы просто хотите убедиться в эффективности решения? В общем пайплайн правильный создаете объект, добавляете к нему RigidBody, к RigidBody добавляете шейпы, если важно можете настроить их как нужно и придавать силу в нужной точке, а не в центре объекта, это позволит достичь более точной симуляции. Если же вы рассматриваете объекты как материальные точки то шейпа сферы будет достаточно и придавать силу в центре шейпа. Так же в настройках щейпа можно выставить маски колизий, по ним будут определяться объекты с которыми шейп может коллизится, можете выставить какую-то опредленную маску этим объектам и объектам с которыми ваши созданные объекты должны колизится. Маска Exclusion нужна чтобы объекты с одинаковими такими масками не колизились, то есть для своих объектов надо выставлять такие маски. Если все объекты у Вас одинаковые, то можете подготовить такой объект в редакторе и сохранить его как NodeReference, а потом в коде уже просто их создавать из NodeReference без дополнительных настроек. 1
sevas55 Posted November 7 Author Posted November 7 Да, задача решена. SOLVED Cпасибо за пояснения и помощь!
mifril Posted November 7 Posted November 7 Единственное что забыл уточнить, что работать с физикой нужно в методе UpdatePhysics, а не в обычном Update. Так как в UpdatePhysics стабильный фреймрейт и и физичный движок вызывает эту функцию перед каждым своим обновлением.
Recommended Posts