So I've been trying to make a compound object work that can have other dynamic objects placed inside it. Found a couple things when adding a simple box to a compound object shape that I'm wondering if anyone has any comments on:
1) The position vector is based on the insertion (center) position of the object and not a global position as stated in the documentation.
2) The size vector gets doubled for the box added to the compound object shape.
I put together a little demo here. You can change the xPos from 0 to anything you like, and it seems to prove that the position vector is indeed based on the object's position and not global. Any change to the scale and you will see the balls fill spill from above or below the rim of the original box object. Not so much an AppGameKit bug, but is there any way we can get documentation improved? Or can someone show me how I have this all wrong somehow?
In this demo press space to generate balls to fill the crate. You can move the camera around with arrow keys and WASD buttons.
// Project: compound_shape_hinge
// Created: 20-09-10
#renderer "Basic" //OpenGL
SetErrorMode(2)
// set window properties
SetWindowTitle( "compound_shape_hinge" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 )
SetPrintSize(20)
type miller //Pass to Reggie when you need a 3 pointer
x as float
y as float
z as float
endtype
global xPos as float = 0 //Adjust this to move the crate / balldrop / plinth assembly from side to side (proves compound shape position is based on object not global)
global ball_size as float = 0.5
ballDropHit as integer = 0 //Spacebar button controls for ball drop
chillTime as float = 0.2
currentTime as float = 0.0
hingeRun as integer = 0 //Backspace button controls for hinge motor
hingeGoBack as integer = 0
hingePulse as float = 500.0
hingeVelocity as float = 1000.0
Create3DPhysicsWorld(1)
myFloor = CreateObjectPlane(32, 32)
RotateObjectGlobalX(myFloor, 90)
SetObjectColor(myFloor, 65, 65, 65, 255)
Create3DPhysicsStaticBody(myFloor)
SetObject3DPhysicsFriction(myFloor, 1000)
SetObject3DPhysicsRollingFriction(myFloor, 1000)
SetObject3DPhysicsRestitution(myFloor, 0)
SetObjectReceiveShadow(myFloor, 1)
/*
* Background objects for height reference
*/
scaleBox1 = CreateObjectBox(4, 1, 4)
SetObjectPosition(scaleBox1, -8, 2, 7)
SetObjectColor(scaleBox1, 133, 133, 133, 255)
Create3DPhysicsDynamicBody(scaleBox1)
scaleBox2 = CreateObjectBox(4, 2, 4)
SetObjectPosition(scaleBox2, -3, 3, GetObjectZ(scaleBox1))
SetObjectColor(scaleBox2, 133, 133, 133, 255)
Create3DPhysicsDynamicBody(scaleBox2)
scaleBox3 = CreateObjectBox(4, 3, 4)
SetObjectPosition(scaleBox3, 3, 4, GetObjectZ(scaleBox1))
SetObjectColor(scaleBox3, 133, 133, 133, 255)
Create3DPhysicsDynamicBody(scaleBox3)
scaleBox4 = CreateObjectBox(4, 4, 4)
SetObjectPosition(scaleBox4, 8, 5, GetObjectZ(scaleBox1))
SetObjectColor(scaleBox4, 133, 133, 133, 255)
Create3DPhysicsDynamicBody(scaleBox4)
/*
* Base to get crate off ground
*/
plinth = CreateObjectBox(3, 1, 3)
SetObjectPosition(plinth, xPos, 0.5, 0)
SetObjectColor(plinth, 166, 166, 166, 255)
Create3DPhysicsStaticBody(plinth)
SetObject3DPhysicsFriction(plinth, 1000)
/*
* Compound Shape: Square Crate
*/
crate_startPos as miller
crate_startPos = reggie(xPos, 2, 0) //X Position is set at top
crate_size as miller
crate_size = reggie(4, 2, 4) //Visible Box Object size, compound shape is half scale of this
vectRot = CreateVector3(0, 0, 0) //Rotation Vector
vectPos = CreateVector3(0, 0, 0) //Position Vector
vectSize = CreateVector3(0, 0, 0) //Size Vector
crate_thickness as float = 0.05 //Wall thickness
crate_shapeScale as float = 0.5 //Size Scale for collions shapes added to compound object
crateObj = CreateObjectBox(crate_size.x, crate_size.y, crate_size.z) //Create box object
SetObjectPosition(crateObj, crate_startPos.x, crate_startPos.y, crate_startPos.z)
SetObjectTransparency(crateObj, 1)
SetObjectColor(crateObj, 204, 0, 255, 150)
Create3DPhysicsDynamicBody(crateObj) //Must be dynamic to create compound shape
SetObject3DPhysicsMass(crateObj, GetObject3DPhysicsMass(crateObj) * 10.0)
SetObject3DPhysicsRestitution(crateObj, 0)
SetObject3DPhysicsCanSleep(crateObj, 0)
SetObjectShapeCompound(crateObj) //This wipes the existing physics shape for the object, to be replaced below
SetVector3(vectPos, 0, 0 - (crate_size.y / 2) + 0.1, 0) //Bottom Base Position - originates from center of compound shape, NOT world origin
SetVector3(vectSize, crate_size.x * crate_shapeScale, crate_thickness, crate_size.z * crate_shapeScale) //Bottom Base Size (Compound shape scale is twice size)
AddObjectShapeBox(crateObj, vectPos, vectRot, vectSize)
SetVector3(vectPos, 0 - (crate_size.x / 2), 0, 0) //Left Wall Position - originates from center of compound shape, NOT world origin
SetVector3(vectSize, crate_thickness, crate_size.y * crate_shapeScale, crate_size.z * crate_shapeScale) //Left Wall Size (Compound shape scale is twice size)
AddObjectShapeBox(crateObj, vectPos, vectRot, vectSize)
SetVector3(vectPos, 0 + (crate_size.x / 2), 0, 0) //Right Wall Position - originates from center of compound shape, NOT world origin
AddObjectShapeBox(crateObj, vectPos, vectRot, vectSize)
SetVector3(vectPos, 0, 0, 0 - (crate_size.x / 2)) //Front Wall Position - originates from center of compound shape, NOT world origin
SetVector3(vectSize, crate_size.x * crate_shapeScale, crate_size.y * crate_shapeScale, crate_thickness) //Front Wall Size (Compound shape scale is twice size)
AddObjectShapeBox(crateObj, vectPos, vectRot, vectSize)
SetVector3(vectPos, 0, 0, 0 + (crate_size.x / 2)) //Rear Wall Position - originates from center of compound shape, NOT world origin
AddObjectShapeBox(crateObj, vectPos, vectRot, vectSize)
DeleteVector3(vectPos)
DeleteVector3(vectRot)
DeleteVector3(vectSize)
/*
* Hinge Object and Joint
*/
hingeStatic = CreateObjectCylinder(5, 0.25, 16)
RotateObjectGlobalZ(hingeStatic, 90)
RotateObjectGlobalY(hingeStatic, 90)
SetObjectColor(hingeStatic, 81, 0, 102, 255)
SetObjectPosition(hingeStatic, xPos + (crate_size.z / 2) + 0, GetObjectY(crateObj) - (crate_size.y / 2), GetObjectZ(crateObj))
Create3DPhysicsStaticBody(hingeStatic)
vectPos = CreateVector3(xPos + (crate_size.x / 2), GetObjectY(crateObj) - (crate_size.y / 2), GetObjectZ(crateObj)) //Position Vector
vectRot = CreateVector3(0, 0, 1) //Axis Rotation Vector -> (0,1,0) vertical, (1,0,0) horizontal along X axis, (0,0,1) horizontal along Z axis
hingeJoint = Create3DPhysicsHingeJoint(hingeStatic, crateObj, vectPos, vectRot, 1)
Set3DPhysicsJointHingeLimits(hingeJoint, -15, 87)
Set3DPhysicsHingeJointMotorIsEnabled(hingeJoint, 1)
Set3DPhysicsHingeJointMaxMotorImpulse(hingeJoint, -5)
DeleteVector3(vectPos)
DeleteVector3(vectRot)
do
print("ScreenFPS() = " + str(ScreenFPS()))
print("press space for balls, move camera with arrows & WASD")
print("press backspace to operate hinge motor, 0 (zero) to return")
/*
* Raw Key Data:
* ~~~~~~~~~~~~~
* 38 = UP, 40 = DOWN, 37 = LEFT, 39 = RIGHT
* 65 = A, 68 = S, 87 = W, 83 = S
* 32 = SPACE, 8 = BACKSPACE, 48 = 0 (zero)
*/
if GetRawKeyState(65) Then MoveCameraLocalX(1, -1)
if GetRawKeyState(68) Then MoveCameraLocalX(1, 1)
if GetRawKeyState(87) Then RotateCameraLocalX(1, -1)
if GetRawKeyState(83) Then RotateCameraLocalX(1, 1)
if GetRawKeyState(38) Then MoveCameraLocalZ(1, 1)
if GetRawKeyState(40) Then MoveCameraLocalZ(1, -1)
if GetRawKeyState(37) Then RotateCameraGlobalY(1, -1)
if GetRawKeyState(39) Then RotateCameraGlobalY(1, 1)
if GetRawKeyState(32) Then ballDropHit = 1
if GetRawKeyState(8) Then hingeRun = 1
if GetRawKeyState(48) Then hingeGoBack = 1
if (ballDropHit)
currentTime = GetMilliseconds()
ballDrop()
endif
if (ballDropHit) and (currentTime > 0.0)
if (GetMilliseconds() > (currentTime + chillTime))
ballDropHit = 0
currentTime = 0.0
endif
endif
if (hingeRun)
Set3DPhysicsHingeJointMaxMotorImpulse(hingeJoint, hingePulse)
Set3DPhysicsHingeJointMotorVelocity(hingeJoint, hingeVelocity)
hingeRun = 0
elseif(hingeGoBack)
Set3DPhysicsHingeJointMaxMotorImpulse(hingeJoint, -500)
Set3DPhysicsHingeJointMotorVelocity(hingeJoint, hingeVelocity)
hingeGoBack = 0
endif
Step3DPhysicsWorld()
Sync()
loop
function ballDrop()
ball_obj = CreateObjectSphere(ball_size, ball_size, 8)
SetObjectPosition(ball_obj, xPos, 12, 0) //Drop balls above the box
SetObjectColor(ball_obj, Random(0,255), Random(0,255), Random(0,255), 255)
Create3DPhysicsDynamicBody(ball_obj)
SetObject3DPhysicsRestitution(ball_obj, 0)
SetObject3DPhysicsMass(ball_obj, GetObject3DPhysicsMass(ball_obj) * 0.25)
endfunction
function reggie(getMillerX as float, getMillerY as float, getMillerZ as float)
millerID as miller
millerID.x = getMillerX
millerID.y = getMillerY
millerID.z = getMillerZ
endfunction millerID