St_AnGer |
26.09.2016 20:43 |
Ответ: PhysX wrapper
Вложений: 1
Побуду немного некрофилом :)
У меня вопрос возник к Знающим!
Как то так получилось, что с такой штукой как джоинты я не работал ни разу в Физиксе. И вот проблемка возникла - соединяю я два тела джоинтом типа Hinge или Fixed. И получается так, что джоинты вообще всех типов работают как "резиновые" если какому-либо из соединяемых тел придать силу или переместить. Как исправить? Упругость пробовал подтягивать - результат не меняется.
Я понимаю что есть bullet wrapper для блица и он более "актуален", если это слово вообще применимо к блицу и всему что с ним связано. С bullet'ом тоже по-экспериментировал сейчас, результат порадовал стабильностью, но там другая проблемка, о ней напишу в теме про bullet, если тут проблему решить не удастся...
зыЖ Нужен именно блиц, потому как это чисто прототип, делаю программный аналог своего робота (ну вот надо мне именно на блице), что бы не спалить дорогущие (нынче) сервоприводы в попытках заставить его ходить. Собственно, джоинты и использую как соединения сервоприводов (fixed - соединения между сервоприводами, hinge - соединение качалки и самого сервопривода)
Вот код, вроде запускается исправно, никаких текстур не требуется. Проблема видна в сочленениях "качалок" и самих сервах (серых кубиков). Качалки имеют сочленение типа Hinge и ограничены во вращении только по оси y, но они всё равно прыгают и по другим осям. Я понимаю что выставлять позицию тела функцией pxBodySetPosition после привязки джоинтом некорректно, но блин, какого хрена даже соединение типа Fixed ведёт себя неадекватно и становится резиновым в этот момент? В буллете такого вроде нету.Есть, проверил. Тогда вопрос - как перенести тело правильно в нужные мне координаты именно ПОСЛЕ установки сочленения?
Код:
;Include "pxServo.bb";
Graphics3D 1024,768,32,2;
AppTitle "Aibo"
pxCreateWorld (1, "");
pxSetGravity (0, -9.8, 0);
WireFrame False;
Global Camera=CreateCamera ();
PositionEntity(Camera, 30, 20, -30);
RotateEntity(Camera, 0, 45, 0);
Global light = CreateLight();
PositionEntity light,0, 100, 0;
pxBodySetCollisionGroupFlag (1, 2, 0);
pxBodySetCollisionGroupFlag (1, 1, 0);
Global legLF1.tServo = createServo(0, 15, 0, 0, -90, 90, False);
EntityColor legLF1\arm, 255, 0, 0
servoRotation(legLF1, 0, 90, 90);
servoSetSpeed (legLF1, 1);
servoSetBetween (legLF1, -65, 25, 1);
Global legLF2.tServo = createServo(-3, 15, -11.5, 0, -90, 90, False);
EntityColor legLF2\arm, 0, 255, 0
servoRotation(legLF2, 0, 0, 90);
servoSetSpeed (legLF2, 1);
servoSetAngle (legLF2, -90);
;Global legLF3.tServo = createServo(-4, 5, -20, 0, -90, 90, False);
;EntityColor legLF3\arm, 0, 0, 255
;servoRotation(legLF3, 0, 0, 0);
;servoSetSpeed (legLF3, 1);
;servoSetBetween (legLF3, 0, 90, 1);
;
;Global legLF4.tServo = createServo(-4, 5, -32, 0, 0, 0, False);
;EntityColor legLF4\arm, 0, 0, 255
;servoRotation(legLF4, 0, 90, 0);
servoConnect (legLF1, servoGetArm(legLF1), servoGetArm(legLF2), legLF1\armPoint1, 0, 1, 1, 0);
;servoConnect (legLF2, servoGetBody(legLF2), servoGetArm(legLF3), legLF2\bodyPoint1, 0);
;servoConnect (legLF3, servoGetBody(legLF3), servoGetBody(legLF4), legLF3\bodyPoint1, 0);
pxBodySetFrozen(servoGetBody(legLF1), 1);
;pxBodySetFrozen(servoGetBody(legLF2), 1);
;pxBodySetFrozen(servoGetBody(legLF3), 1);
;pxBodySetFrozen(servoGetBody(legLF4), 1);
Global pointer = CreateCylinder()
ScaleEntity pointer, 0.125, 80, 0.125;
PositionEntity pointer, 0, 80, 0
Global mxs# = 0;
Global mys# = 0;
Global camY# = 0;
Global speed# = 1.0;
Const GameUPS=60 ; Updates per second
Local Period=1000/GameUPS
Local FrameTime=MilliSecs()-Period
Local Tween#, Ticks,i,Remaining,StartTime,Elapsed
MoveMouse(GraphicsWidth()/2, GraphicsHeight()/2);
While Not KeyHit(1)
mxs = -MouseXSpeed()*0.125;
mys = MouseYSpeed()*0.125;
MoveMouse(GraphicsWidth()/2, GraphicsHeight()/2);
StartTime = MilliSecs();
Repeat
Elapsed=MilliSecs()-FrameTime;
Until Elapsed;
Ticks=Elapsed / Period;
Tween=Float(Elapsed Mod Period)/Float(Period);
For i=1 To Ticks
FrameTime=FrameTime+Period;
If i=Ticks Then
CaptureWorld;
End If
UpdateGame();
UpdateWorld();
Next
RenderWorld Tween;
Remaining = Period - (MilliSecs() - StartTime);
If Remaining > 1 Then
Delay (Remaining-1) ; Free some CPU time
End If
Flip;
Wend
btDestroyWorld()
End
Function UpdateGame()
If (KeyDown(17)) MoveEntity Camera, 0, 0, speed;
If (KeyDown(31)) MoveEntity Camera, 0, 0, -speed;
If (KeyDown(30)) MoveEntity Camera, -speed, 0, 0;
If (KeyDown(32)) MoveEntity Camera, speed, 0, 0;
camY = camY + mys;
If (camY <= -75)
camY = -75;
Else If (camY >= 75)
camY = 75;
End If
TurnEntity Camera, 0, mxs, 0;
RotateEntity Camera, camY, EntityYaw(Camera,1), 0;
If KeyHit(57)
; servoToggleAll();
servoPosition(legLF1, 0, 20, 0);
End If
updateServos ();
pxRenderPhysic(60, 0);
End Function
Type tServo
Field angle#, angleBetweenMin#, angleBetweenMax#;
Field min#, max#;
Field speed#;
Field move%;
Field dest#;
Field posX#, posY#;
Field parent%;
Field body%, bodyPoint1%, bodyPoint2%;
Field arm%, armPoint1, armPoint2;
Field cycleMirror%;
Field pxBody%, pxArm%, pxJoint%, pxJointParent%, pxJointChild%, pxParent;
End Type
Function createServo.tServo(px#, py#, pz#, angle#,min#,max#, double% = False)
Local s.tServo = New tServo;
s\angle = angle;
s\min = min;
s\max = max;
s\cycleMirror = False;
s\move = False;
s\parent = 0;
s\body = CreateCube();
ScaleEntity s\body, 2.0, 3.6, 4.0;
PositionEntity s\body, px, py, pz;
; Local body2 = CreateCube();
; ScaleEntity body2, 1.6, 0.4, 3.6;
; PositionEntity body2, px+0, py+4.0, pz+0;
; EntityTexture body2,tex;
; EntityParent body2, s\body;
s\bodyPoint1 = CreateSphere(8);
ScaleEntity s\bodyPoint1, 0.5, 0.5, 0.5;
PositionEntity s\bodyPoint1, px, py+3.6, pz+4.0, 1;
EntityParent s\bodyPoint1, s\body;
EntityColor s\bodyPoint1, 255, 0, 0;
s\bodyPoint2 = CreateSphere(8);
ScaleEntity s\bodyPoint2, 0.5, 0.5, 0.5;
PositionEntity s\bodyPoint2, px, py+3.6, pz-4.0, 1;
EntityParent s\bodyPoint2, s\body
EntityColor s\bodyPoint2, 0, 255, 0;
s\arm = CreateCube();
ScaleEntity s\arm, 0.6, 0.3, 4.6;
PositionEntity s\arm, px, py+4.6, pz+2.4;
s\armPoint1 = CreateSphere(8);
ScaleEntity s\armPoint1, 0.5, 0.5, 0.5;
PositionEntity s\armPoint1, px, py+4.6, pz+2.4+4.6;
EntityParent s\armPoint1, s\arm
EntityColor s\armPoint1, 255, 0, 0;
s\armPoint2 = CreateSphere(8);
ScaleEntity s\armPoint2, 0.5, 0.5, 0.5;
PositionEntity s\armPoint2, px, py+4.6, pz+2.4-4.6;
EntityParent s\armPoint2, s\arm
EntityColor s\armPoint2, 0, 255, 0;
s\pxBody = pxBodyCreateCube(2.0, 3.6, 4.0, 1);
pxBodySetPosition(s\pxBody, px, py, pz);
s\pxArm = pxBodyCreateCube(0.6, 0.3, 4.6, 1);
pxBodySetPosition(s\pxArm, pxBodyGetPositionX(s\pxBody)+0, pxBodyGetPositionY(s\pxBody)+4.6, pxBodyGetPositionZ(s\pxBody)+2.4);
s\pxJoint = pxJointCreateHinge (s\pxBody, s\pxArm, pxBodyGetPositionX(s\pxBody)+0, pxBodyGetPositionY(s\pxBody)+4.6, pxBodyGetPositionZ(s\pxBody)+2.4, 0, 1, 0);
pxJointHingeSetLimit (s\pxJoint, min, max);
Return s;
End Function
Function servoRotation(s.tServo, rX# = 0, rY# = 0, rZ# = 0, flag% = True)
If (s <> Null)
Local x#, y#, z#;
Local x0#, y0#, z0#;
Local x1#, y1#, z1#;
Local x2#, y2#, z2#;
Local x3#, y3#, z3#;
If (flag)
servoRotation(s, 0, 0, 0, False);
End If
If (rX = 0 And rY = 0 And rZ = 0)
x# = pxBodyGetPositionX(s\pxBody);
y# = pxBodyGetPositionY(s\pxBody);
z# = pxBodyGetPositionZ(s\pxBody);
pxBodySetPosition(s\pxArm, x, y+4.6, z+2.4);
Else
x# = pxBodyGetPositionX(s\pxBody);
y# = pxBodyGetPositionY(s\pxBody);
z# = pxBodyGetPositionZ(s\pxBody);
x0# = pxBodyGetPositionX(s\pxArm);
y0# = pxBodyGetPositionY(s\pxArm);
z0# = pxBodyGetPositionZ(s\pxArm);
x1# = x+(x0-x)*Cos(rZ)+(y-y0)*Sin(rZ);
y1# = y+(x0-x)*Sin(rZ)+(y0-y)*Cos(rZ);
z1# = z0;
x2# = x+(x1-x)*Cos(rY)+(z-z1)*Sin(rY);
y2# = y1;
z2# = z+(x1-x)*Sin(rY)+(z1-z)*Cos(rY);
x3# = x2;
y3# = y+(y2-y)*Cos(rX)+(z-z2)*Sin(rX);
z3# = z+(y2-y)*Sin(rX)+(z2-z)*Cos(rX);
pxBodySetPosition(s\pxArm, x3, y3, z3);
End If
pxBodySetRotation(s\pxArm, rX, rY, rZ);
pxBodySetRotation(s\pxBody, rX, rY, rZ);
End If
End Function
Function servoPosition(s.tServo, pX# = 0.0, pY# = 0.0, pZ# = 0.0)
If (s <> Null)
Local nX# = pxBodyGetPositionX(s\pxBody) - pxBodyGetPositionX(s\pxArm)
Local nY# = pxBodyGetPositionY(s\pxBody) - pxBodyGetPositionY(s\pxArm)
Local nZ# = pxBodyGetPositionZ(s\pxBody) - pxBodyGetPositionZ(s\pxArm)
pxBodySetPosition(s\pxBody, pX, pY, pZ);
pxBodySetPosition(s\pxArm, pX+nX, pY+nY, pZ+nZ);
End If
End Function
Function servoGetArm%(s.tServo)
If (s <> Null)
Return s\pxArm;
End If
Return 0;
End Function
Function servoGetBody%(s.tServo)
If (s <> Null)
Return s\pxBody;
End If
Return 0;
End Function
Function servoSetAngle(s.tServo, angle#)
If (s <> Null)
s\dest = angle;
If (s\dest < s\min)
s\dest = s\min;
Else If (s\dest > s\max)
s\dest = s\max;
End If
End If
End Function
Function servoSetSpeed(s.tServo, speed# = 1)
If (s <> Null)
s\speed = speed;
End If
End Function
Function servoStop(s.tServo)
If (s <> Null)
s\move = False;
End If
End Function
Function servoStart(s.tServo)
If (s <> Null)
s\move = True;
End If
End Function
Function servoStopAll()
Local s.tServo;
For s = Each tServo
servoStop(s);
Next
End Function
Function servoStartAll()
Local s.tServo;
For s = Each tServo
servoStart(s);
Next
End Function
Function servoToggle(s.tServo)
If (s <> Null)
If (s\move)
s\move = False;
Else
s\move = True
End If
End If
End Function
Function servoToggleAll()
Local s.tServo;
For s = Each tServo
servoToggle(s);
Next
End Function
Function servoConnect(s.tServo, parent, child, entity1%, angle# = 90, fX% = 0, fY% = 1, fZ% = 0)
If (s.tServo <> Null)
Local g1 = 1;
Local g2 = 1;
Local pX1# = pxBodyGetPositionX(s\pxBody);
Local pY1# = pxBodyGetPositionY(s\pxBody);
Local pZ1# = pxBodyGetPositionZ(s\pxBody);
s\pxJointChild = pxJointCreateHinge(parent, child, pX1, pY1, pZ1, fX, fY, fZ);
pxJointHingeSetLimit s\pxJointChild, 0, 0;
pxJointHingeSetSpring s\pxJointChild, 0, 0;
pxJointHingeSetMotor s\pxJointChild, 10, 0
End If
End Function
Function servoSetBetween(s.tServo, betweenMin# = 0, betweenMax# = 0, dir% = 1)
If (s <> Null)
s\angleBetweenMax = betweenMax;
s\angleBetweenMin = betweenMin;
If (betweenMin = betweenMax)
s\cycleMirror = False;
Else
s\cycleMirror = True;
If (dir > 0)
s\dest = s\angleBetweenMax;
Else
s\dest = s\angleBetweenMin;
End If
End If
End If
End Function
Function updateServos()
Local s.tServo;
For s = Each tServo
pxBodySetEntity(s\body, s\pxBody);
pxBodySetEntity(s\arm, s\pxArm);
If (s\parent)
End If
If (s\move)
If (s\angle < s\dest)
s\angle = s\angle + s\speed;
Else If (s\angle > s\dest)
s\angle = s\angle - s\speed;
Else
If (s\cycleMirror)
If (s\dest = s\angleBetweenMax)
s\dest = s\angleBetweenMin;
Else If (s\dest = s\angleBetweenMin)
s\dest = s\angleBetweenMax;
End If
Else
s\angle = s\dest;
End If
End If
End If
Next
End Function
А получить хочу в конечном итоге примерно вот что (на пробел это нечто начинает невнятно шевелить конечностями), только с физикой (шоб ходило прям как мой роботЪ, Только виртуально и не кроша сервоприводы пачками :-) ).
В архиве работающее приложение (компилил из под вайна на маке... знаю, изващенец :-D ): Вложение 22496.
Под катом код этого приложения (разница только в отсутствии в коде использования текстур):
Код:
Graphics3D 1024,768,32,2;
;Include "servo.bb";
WireFrame False;
;Global tex1 = LoadTexture ("tex1.jpg");
;ScaleTexture tex1, 10, 10;
;Global plane = CreatePlane();
;EntityTexture plane,tex1;
Global Camera=CreateCamera ();
PositionEntity(Camera, 30, 40, -30);
RotateEntity(Camera, 0, 45, 0);
Global light = CreateLight();
PositionEntity light,0, 100, 0;
Global legLF1.tServo = createServo(0, -90, 90, False, False);
servoPosition (legLF1, 0, 0, 0);
servoRotate (legLF1, 0, 90, 90);
servoSetSpeed (legLF1, 1);
servoSetBetween (legLF1, -65, 25, 1);
Global legLF2.tServo = createServo(0, -90, 90, True, True);
servoPosition (legLF2, -3, 0, -9);
servoRotate (legLF2, 0, 0, 90);
servoSetAngle (legLF2, -90);
servoSetSpeed (legLF2, 1);
Global legLF3.tServo = createServo(0, -90, 90, True, True);
servoPosition (legLF3, -3, 0, -20);
servoRotate (legLF3, 0, 0, 0);
servoSetSpeed (legLF3, 1);
servoSetBetween (legLF3, 0, 90, 1);
Global footLF = CreateCube();
ScaleEntity footLF, 4, 1, 2;
PositionEntity footLF, -3, 0, -30;
RotateEntity footLF, 90, 0, 0
Global legRF1.tServo = createServo(0, -90, 90, False, False);
servoPosition (legRF1, 0, 0, 0);
servoRotate (legRF1, 0, 90, -90);
servoSetSpeed (legRF1, 1);
servoSetBetween (legRF1, -25, 65, 1);
Global legRF2.tServo = createServo(0, -90, 90, True, True);
servoPosition (legRF2, -3, 0, 9);
servoRotate (legRF2, 180, 0, -90);
servoSetAngle (legRF2, -90);
servoSetSpeed (legRF2, 1);
Global legRF3.tServo = createServo(0, -90, 90, True, True);
servoPosition (legRF3, -3, 0, 20);
servoRotate (legRF3, 180, 0, 0);
servoSetSpeed (legRF3, 1);
servoSetBetween (legRF3, 0, 90, 1);
Global footRF = CreateCube();
ScaleEntity footRF, 4, 1, 2;
PositionEntity footRF, -3, 0, 30;
RotateEntity footRF, 90, 0, 0
Global legLB1.tServo = createServo(0, -90, 90, False, False);
servoPosition (legLB1, 0, 0, 0);
servoRotate (legLB1, 0, 90, 90);
servoSetSpeed (legLB1, 1);
servoSetBetween (legLB1, -45, 45, -1);
Global legLB2.tServo = createServo(0, -90, 90, True, True);
servoPosition (legLB2, -3, 0, -9);
servoRotate (legLB2, 0, 0, 90);
servoSetAngle (legLB2, -90);
servoSetSpeed (legLB2, 1);
Global legLB3.tServo = createServo(0, -90, 90, True, True);
servoPosition (legLB3, -3, 0, -20);
servoRotate (legLB3, 0, 0, 0);
servoSetSpeed (legLB3, 1);
servoSetBetween (legLB3, 0, 90, -1);
Global footLB = CreateCube();
ScaleEntity footLB, 4, 1, 2;
PositionEntity footLB, -3, 0, -30;
RotateEntity footLB, 90, 0, 0
Global legRB1.tServo = createServo(0, -90, 90, False, False);
servoPosition (legRB1, 0, 0, 0);
servoRotate (legRB1, 0, 90, -90);
servoSetSpeed (legRB1, 1);
servoSetBetween (legRB1, -45, 45, -1);
Global legRB2.tServo = createServo(0, -90, 90, True, True);
servoPosition (legRB2, -3, 0, 9);
servoRotate (legRB2, 180, 0, -90);
servoSetAngle (legRB2, -90);
servoSetSpeed (legRB2, 1);
Global legRB3.tServo = createServo(0, -90, 90, True, True);
servoPosition (legRB3, -3, 0, 20);
servoRotate (legRB3, 180, 0, 0);
servoSetSpeed (legRB3, 1);
servoSetBetween (legRB3, 0, 90, -1);
Global footRB = CreateCube();
ScaleEntity footRB, 4, 1, 2;
PositionEntity footRB, -3, 0, 30;
RotateEntity footRB, 90, 0, 0
Global body = CreatePivot();
ScaleEntity body, 1, 1, 1;
Global bodyMesh = CreateCube();
ScaleEntity bodyMesh, 15,0.1,5;
PositionEntity bodyMesh, 0, -2.1, 0;
EntityParent bodyMesh, body;
servoAddEntity (legLF1, servoGetArm(legLF2));
servoAddEntity (legLF2, servoGetArm(legLF3));
servoAddEntity (legLF3, footLF);
servoAddEntity (legRF1, servoGetArm(legRF2));
servoAddEntity (legRF2, servoGetArm(legRF3));
servoAddEntity (legRF3, footRF);
servoAddEntity (legLB1, servoGetArm(legLB2));
servoAddEntity (legLB2, servoGetArm(legLB3));
servoAddEntity (legLB3, footLB);
servoAddEntity (legRB1, servoGetArm(legRB2));
servoAddEntity (legRB2, servoGetArm(legRB3));
servoAddEntity (legRB3, footRB);
servoPosition (legLF1, -12, 0, -5);
servoPosition (legRF1, -12, 0, 5);
servoPosition (legLB1, 12, 0, -5);
servoPosition (legRB1, 12, 0, 5);
servoParent (legLF1, body);
servoParent (legLB1, body);
servoParent (legRF1, body);
servoParent (legRB1, body);
PositionEntity body, 0, 30, 0;
;servoStartAll();
Global mxs# = 0;
Global mys# = 0;
Global camY# = 0;
Global speed# = 1.0;
Const GameUPS=60 ; Updates per second
Local Period=1000/GameUPS
Local FrameTime=MilliSecs()-Period
Local Tween#, Ticks,i,Remaining,StartTime,Elapsed
While Not KeyHit(1)
mxs = -MouseXSpeed()*0.25;
mys = MouseYSpeed()*0.25;
MoveMouse(GraphicsWidth()/2, GraphicsHeight()/2);
StartTime = MilliSecs();
Repeat
Elapsed=MilliSecs()-FrameTime;
Until Elapsed;
Ticks=Elapsed / Period;
Tween=Float(Elapsed Mod Period)/Float(Period);
For i=1 To Ticks
FrameTime=FrameTime+Period;
If i=Ticks Then
CaptureWorld;
End If
UpdateGame();
UpdateWorld();
Next
RenderWorld Tween;
Remaining = Period - (MilliSecs() - StartTime);
If Remaining > 1 Then
Delay (Remaining-1) ; Free some CPU time
End If
Flip;
Wend
End
Function UpdateGame()
If (KeyDown(17)) MoveEntity Camera, 0, 0, speed;
If (KeyDown(31)) MoveEntity Camera, 0, 0, -speed;
If (KeyDown(30)) MoveEntity Camera, -speed, 0, 0;
If (KeyDown(32)) MoveEntity Camera, speed, 0, 0;
camY = camY + mys;
If (camY <= -75)
camY = -75;
Else If (camY >= 75)
camY = 75;
End If
TurnEntity Camera, 0, mxs, 0;
RotateEntity Camera, camY, EntityYaw(Camera,1), 0;
If KeyHit(57)
servoToggleAll();
End If
updateServos ();
End Function
Type tServo
Field angle#, angleBetweenMin#, angleBetweenMax#;
Field min#, max#;
Field mainArm%;
Field speed#;
Field move%;
Field dest#;
Field posX#, posY#;
Field parent%;
Field pivotBody%, pivotArm%
Field body%, arm%;
Field cycleMirror%;
Field pxBody%;
End Type
Function createServo.tServo(angle#,min#,max#, double% = False, mainArm = False)
Local s.tServo = New tServo;
s\angle = angle;
s\min = min;
s\max = max;
s\mainArm = mainArm
s\cycleMirror = False;
s\move = False;
s\pivotBody = CreatePivot();
s\pivotArm = CreatePivot();
; Local tex = LoadTexture ("bricks.jpg");
s\body = CreateCube();
ScaleEntity s\body, 2.0, 3.6, 4.0;
; EntityTexture s\body,tex;
Local body2 = CreateCube();
ScaleEntity body2, 1.6, 0.4, 3.4;
PositionEntity body2, 0.2, 3.8, 0.2;
; EntityTexture body2,tex;
EntityParent body2, s\body;
s\arm = CreateCylinder();
If (double)
ScaleEntity s\arm, 0.55, 4.8, 0.55;
Else
ScaleEntity s\arm, 0.55, 4, 0.55;
PositionEntity s\arm, 0, 0.6, 0;
End If
Local arm2 = CreateCube();
ScaleEntity arm2, 0.6, 0.3, 4.6;
PositionEntity arm2, 0, 4.6, 0;
EntityParent arm2, s\arm;
If (double)
Local arm3 = CreateCube();
ScaleEntity arm3, 0.6, 0.3, 4.6;
PositionEntity arm3, 0, -4.6, 0;
EntityParent arm3, s\arm;
End If
EntityParent s\body, s\pivotBody;
EntityParent s\arm, s\pivotArm;
If (s\mainArm)
PositionEntity s\body, 0, -0.2, -2.4;
EntityParent s\pivotBody, s\pivotArm;
Else
PositionEntity s\pivotArm, 0, 0.4, 2.4;
EntityParent s\pivotArm, s\pivotBody;
End If
If (s\mainArm)
RotateEntity s\pivotArm, 0, s\angle, 0;
Else
RotateEntity s\pivotBody, 0, s\angle, 0;
End If
Return s;
End Function
Function servoRotate(s.tServo, rX# = 0.0, rY# = 0.0, rZ# = 0.0)
If (s <> Null)
If (s\mainArm)
RotateEntity s\pivotArm, rX, rY, rZ;
Else
RotateEntity s\pivotBody, rX, rY, rZ;
End If
End If
End Function
Function servoPosition(s.tServo, pX# = 0.0, pY# = 0.0, pZ# = 0.0)
If (s <> Null)
If (s\mainArm)
PositionEntity s\pivotArm, pX, pY, pZ;
Else
PositionEntity s\pivotBody, pX, pY, pZ;
End If
End If
End Function
Function servoParent(s.tServo, parent)
If (s <> Null)
If (s\mainArm)
EntityParent s\pivotArm, parent;
Else
EntityParent s\pivotBody, parent;
End If
End If
End Function
Function servoGetArm%(s.tServo)
If (s <> Null)
If (s\mainArm)
Return s\pivotArm;
Else
Return s\pivotBody;
End If
End If
Return 0;
End Function
Function servoGetBody%(s.tServo)
If (s <> Null)
If (s\mainArm)
Return s\pivotBody;
Else
Return s\pivotArm;
End If
End If
Return 0;
End Function
Function servoSetAngle(s.tServo, angle#)
If (s <> Null)
s\dest = angle;
If (s\dest < s\min)
s\dest = s\min;
Else If (s\dest > s\max)
s\dest = s\max;
End If
End If
End Function
Function servoSetSpeed(s.tServo, speed# = 1)
If (s <> Null)
s\speed = speed;
End If
End Function
Function servoStop(s.tServo)
If (s <> Null)
s\move = False;
End If
End Function
Function servoStart(s.tServo)
If (s <> Null)
s\move = True;
End If
End Function
Function servoStopAll()
Local s.tServo;
For s = Each tServo
servoStop(s);
Next
End Function
Function servoStartAll()
Local s.tServo;
For s = Each tServo
servoStart(s);
Next
End Function
Function servoToggle(s.tServo)
If (s <> Null)
If (s\move)
s\move = False;
Else
s\move = True
End If
End If
End Function
Function servoToggleAll()
Local s.tServo;
For s = Each tServo
servoToggle(s);
Next
End Function
Function servoAddEntity(s.tServo, entity%)
If (s.tServo <> Null And entity% <> 0)
If (s\mainArm)
EntityParent entity, s\pivotBody;
Else
EntityParent entity, s\pivotArm;
End If
End If
End Function
Function servoSetBetween(s.tServo, betweenMin# = 0, betweenMax# = 0, dir% = 1)
If (s <> Null)
s\angleBetweenMax = betweenMax;
s\angleBetweenMin = betweenMin;
If (betweenMin = betweenMax)
s\cycleMirror = False;
Else
s\cycleMirror = True;
If (dir > 0)
s\dest = s\angleBetweenMax;
Else
s\dest = s\angleBetweenMin;
End If
End If
End If
End Function
Function updateServos()
Local s.tServo;
For s = Each tServo
If (s\move)
If (s\angle < s\dest)
s\angle = s\angle + s\speed;
Else If (s\angle > s\dest)
s\angle = s\angle - s\speed;
Else
If (s\cycleMirror)
If (s\dest = s\angleBetweenMax)
s\dest = s\angleBetweenMin;
Else If (s\dest = s\angleBetweenMin)
s\dest = s\angleBetweenMax;
End If
Else
s\angle = s\dest;
End If
End If
If (s\mainArm)
RotateEntity s\pivotBody, 0, s\angle, 0;
Else
RotateEntity s\pivotArm, 0, s\angle, 0;
End If
End If
Next
End Function
upd Почитал интернеты, по ходу дела никак проблему не решить - джоинты на всех физ.движках так себя ведут под нагрузкой. Это прискорбно :(.
upd2 На Bullet'е почти получилось реализовать то, что я хотел. Там джоинты менее "резиновые", но всё равно этот эффект никак не получается ещё больше снизить...
|