Ограничение реактора Rag Doll (тряпичная кукла, рис. 1) позволяет сочленять два объекта, сохраняя три степени свободы: вращение пространств родительского и дочернего объектов ограничения относительно Twist-оси, вращение Twist-оси дочернего объекта относительно родительского объекта и угловое перемещение дочернего объекта относительно родительского объекта.
Рис. 1. Представление ограничения Rag Doll в видовом порте Front
Эти степени свободы управляются параметрами TwistMin, TwistMax, ConeMin, ConeMax, PlaneMin и PlaneMax.
Ограничение имеет два пространства – родительское и дочернее (рис. 2).
Рис. 2. Оси координат родительского (зеленое) и дочернего (коричневое) Rag Doll-пространств
Оси координат пространств можно переместить или повернуть, выбрав в иерархии ограничения соответствующее пространство (рис. 3).
Рис. 3. Можно переместить или повернуть оси координат родительского пространства
Оперативно пространства можно выровнять по дочернему или родительскому объекту или по дочернему или родительскому пространству.
Изначально пространства выровнены по родительскому объекту – начало координат обоих пространств находится в базовой точке родительского объекта.
Ясно, что решение ограничения зависит не только от значений его свойств, но и от положения родительского и дочернего пространств, а также от положения базовых точек сочленяемых объектов.
В примере посредством Rag Doll сочленяются два конуса, которые затем под действием силы гравитации начинают падать. Их движению мешает похожий на лестницу объект (рис. 4).
Рис. 4. Rag Doll-сочленение конусов
Результат обеспечивается следующим кодом:
delete $*
aRng = 150
animationRange = interval 0f aRng
timeConfiguration.PlaybackLoop = false
-- Число ступенек лестницы
ns = 4
-- Высота ступеньки
hs = 80
h = ns * hs
bx = box lengthsegs:1 widthsegs:1 heightsegs:ns length:300 width:10 height:h mapcoords:on pos:[0.5 * h, 0, -0.5 * h] wireColor:[225, 198, 87]
convertToMesh bx
hs2 = 1.5 * hs
vld = true
case ns of (
4: (
-- Создаем лестницу
meshop.ExtrudeFaces bx #{29..34} hs2 0
meshop.ExtrudeFaces bx #{29..32} hs2 0
meshop.ExtrudeFaces bx #{29..30} (2.0 * hs2) 0
)
5: (
-- Создаем лестницу
meshop.ExtrudeFaces bx #{35..42} hs2 0
meshop.ExtrudeFaces bx #{35..40} hs2 0
meshop.ExtrudeFaces bx #{35..38} (2.0 * hs2) 0
meshop.ExtrudeFaces bx #{35..36} (3.0 * hs2) 0
)
default: (
messageBox("Invalid number of steps")
vld = false
)
)
if vld do (
update bx
max tool zoomExtents
hcs = 0.75 * hs
cn = cone radius1:25 radius2:0 height:hcs pos:[1.25 * hs, 0, 0.5 * h] wireColor:[135, 110, 8]
cn2 = cone radius1:25 radius2:0 height:hcs pos:[1.25 * hs, 0, 0.5 * h + 2 * hcs] wireColor: [6, 135, 113]
rotate cn2 180 [1, 0, 0]
-- Перемещаем базовые точки в вершины конусов
cn.Pivot += [0, 0, hcs]
cn2.Pivot -= [0, 0, hcs]
-- Коллекция твердых тел
RBC = RBCollection()
RBC.RigidBodies = #(bx, cn, cn2)
-- Регулируем свойства объектов коллекции твердых тел
rb = RBC.GetRigidObject 1
rb.Unyielding = true
rb.Friction = 0.7
rb.Elasticity = 0.0
rb.SimulationGeometry = 2 -- Mesh Convex Hull (выпуклая оболочка)
--
rb = RBC.GetRigidObject 2
rb.Mass =12.5
rb.Friction = 0.5
rb.Elasticity = 0.0
rb.SimulationGeometry = 2
--
rb = RBC.GetRigidObject 3
rb.Mass = 9.5
rb.Friction = 0.5
rb.Elasticity = 0.0
rb.SimulationGeometry = 2
--
rd = rctRagDoll()
rd.ChildBody = cn2
rd.HasParent = true
rd.ParentBody = cn
-- Регулируем свойства ограничения Rag Doll
-- -175 - 175
-- Ограничивает вращение пространств ограничения относительно Twist-оси
rd.TwistMin = -15
rd.TwistMax = 15
-- -175 - 175
-- Ограничивает вращение Twist-оси дочернего объекта относительно родительского объекта
rd.ConeMin = -50
rd.ConeMax = 50
-- -90 - 90
-- Ограничивает угловое перемещение дочернего объекта
rd.PlaneMin = -25
rd.PlaneMax = 25
-- Решатель ограничений
cs = cSolver()
cs.RBCollection = RBC
cs.AddConstraint rd
reactor.EndFrame = aRng
reactor.PreviewAnimation()
omniLight pos:[-415, -130, 340]
omniLight pos:[-250, -320, 220]
-- reactor.CreateAnimation true
-- playAnimation()
)
Реактор имеет схожие с Rag Doll ограничения, например Hinge (петля) или Point-Point (точка-точка), позволяющие сочленять два объекта. Ограничения отличаются предоставляемыми степенями свободы. Программирование таких ограничений несущественно отличается от программирования Rag Doll.