And I rediscover why I completely stopped working on Omeganaut: setting the collision shapes is a hassle. We can't see the collision Bodies of ZGEBullet, so I had to do some magic with basic visible meshes and transformation scales. But it is still NOT simple.
I just spent 3 hours making this strip down example, and being reminded what a mess it is.
- Move the mouse around to cast a ray on the model and see if it collides
- Rotate the model with WASD/Arrows
- Change the model with Spacebar
Here are the model examples:
- Pyramid: as there is no pyramid collision shape, it's a bit tricky with just a cone
- Trunk: the cylinder shape works fine
- Building: same for the box
- Plane: made out of compound shapes. This one is broken, just to show how COMPLICATED it is to set the thing right
So I have a few things to discuss with you guys in order to see through this, if you want to join.
For starters, do you think some kind of visual editor would be possible to do, using what I started? Such as, moving the visible shape around would modify the Bullet Shape. I'm not sure if that is possible, that might just crash the game, as I remember ZgeBullet being a bit picky when playing with shapes that already are in memory. But I'm not sure, I need to try.
Or maybe the logic I used is overly complicated? The problem is that I will have a lot of complex shapes afterward, such as the plane. And putting them together is hell of a task.
Another thing, do I need to create several cubes shapes such as :
Shape_Building = zbtCreateBoxShape(1.0, 2.5, 2.0);
Shape_BigBuilding = zbtCreateBoxShape(4.0, 4.0, 2.0);
Shape_PetitCube = zbtCreateBoxShape(0.1, 0.1, 0.1);
Or should I use void zbtSetShapeLocalScaling(xptr shape, float x, float y, float z) {} on a Shape_BasicCube = zbtCreateBoxShape(1.0, 1.0, 1.0);
I am this close to only use simple cubes à la Minecraft for everything...
Lastly, I will try to see how zbtCreateConvexHullShape and zbtCreateTriangleMeshShape works. It might just be possible to add a simplified collision shape made directly in Blender, just like the rest. That would greatly simplify the process, and there are not that much objects running at the same time so it should be fine, if it is even possible.
Anyway, here's the thing:
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FixedFrameRate="60" ScreenMode="0" FileVersion="2">
<OnLoaded>
<ZExternalLibrary ModuleName="opengl32">
<BeforeInitExp>
<![CDATA[//
if (ANDROID)
{
if(App.GLBase==0) this.ModuleName="libGLESv1_CM.so";
else this.ModuleName="libGLESv2.so";
}
else if (LINUX)
{
this.ModuleName = "libGL.so";
}
else
{
this.ModuleName = "opengl32";
}]]>
</BeforeInitExp>
<Source>
<![CDATA[const int GL_DEPTH_BUFFER_BIT = 0x0100;
void glClear(int mode){}
/* Boolean */
const int GL_ZERO = 0;
const int GL_ONE = 1;
/* BlendingFactorDest */
//const int GL_SRC_COLOR = 0x0300;
const int GL_ONE_MINUS_SRC_COLOR = 0x0301;
const int GL_SRC_ALPHA = 0x0302;
const int GL_ONE_MINUS_SRC_ALPHA = 0x0303;
//const int GL_DST_ALPHA = 0x0304;
//const int GL_ONE_MINUS_DST_ALPHA = 0x0305;
/* BlendingFactorSrc */
//const int GL_DST_COLOR = 0x0306;
const int GL_ONE_MINUS_DST_COLOR = 0x0307;
//const int GL_SRC_ALPHA_SATURATE = 0x0308;
/* EnableCap */
const int GL_BLEND = 0x0BE2;
//const int GL_COLOR_LOGIC_OP = 0x0BF2;
/* LogicOp */
//const int GL_INVERT = 0x150A;
void glDisable(int cap){}
void glEnable(int cap){}
//void glLogicOp(int opcode){}
//void glColor3f(float red, float green, float blue){}
void glBlendFunc(int sfactor, int dfactor){}
// Pour le screenshot
void glReadPixels(int x, int y, int width, int height, int format, int type, xptr data){}
// Coloration des vaisseaux sur un Hit avec une Light
//void glLightfv(int light, int pname, xptr params){}
// VR
//void glClear(int mask){}
void glViewport(int X, int Y, int Width, int Height){}
void glGetIntegerv(int pname, xptr params){}]]>
</Source>
</ZExternalLibrary>
<ZExternalLibrary Comment="Bullet 3D physics" ModuleName="ZgeBullet_x64">
<BeforeInitExp>
<![CDATA[//
if(ANDROID)
{
this.ModuleName = "./libZgeBullet.so";
}
else if(LINUX)
{
this.ModuleName = "./ZgeBullet.so";
}
else
{
this.ModuleName = "ZgeBullet_x64";
}]]>
</BeforeInitExp>
<Source>
<![CDATA[/*
ZgeBullet Library, a wrapper for the Bullet Physics Library.
http://bulletphysics.org
Project home
https://github.com/Rado-1/ZgeBullet
Download Windows DLL and Android shared library from
https://github.com/Rado-1/ZgeBullet/releases
Copyright (c) 2012-2016 Radovan Cervenka
Version: 2.4 (2016-09-07)
*/
// Constants
// Triangle mesh types
//const int ZBT_TRIANGLE_CONVEX_HULL_MESH = 1;
//const int ZBT_TRIANGLE_CONCAVE_STATIC_MESH = 2;
//const int ZBT_TRIANGLE_CONCAVE_DEFORMABLE_MESH = 3;
// Activation states
//const int ZBT_ACTIVE_TAG = 1;
//const int ZBT_ISLAND_SLEEPING = 2;
//const int ZBT_WANTS_DEACTIVATION = 3;
//const int ZBT_DISABLE_DEACTIVATION = 4;
//const int ZBT_DISABLE_SIMULATION = 5;
// Default values of constraint limits
//const float ZBT_DEFAULT_HINGE_SOFTNESS = 0.9;
//const float ZBT_DEFAULT_HINGE_BIAS_FACTOR = 0.3;
//const float ZBT_DEFAULT_HINGE_RELAXATION_FACTOR = 1.0;
//const float ZBT_DEFAULT_CONE_TWIST_SOFTNESS = 1.0;
//const float ZBT_DEFAULT_CONE_TWIST_BIAS_FACTOR = 0.3;
//const float ZBT_DEFAULT_CONE_TWIST_RELAXATION_FACTOR = 1.0;
// Vehicle tunning defaults
//const float ZBT_DEFAULT_VEHICLE_SUSP_STIFFNESS = 5.88;
//const float ZBT_DEFAULT_VEHICLE_SUSP_COMPRESSION = 0.83;
//const float ZBT_DEFAULT_VEHICLE_SUSP_DAMPING = 0.88;
//const float ZBT_DEFAULT_VEHICLE_SUSP_MAX_SUSP_TRAVEL_CM = 500.0;
//const float ZBT_DEFAULT_VEHICLE_SUSP_FORCE = 6000.0;
//const float ZBT_DEFAULT_VEHICLE_FRICTION_SLIP = 10.5;
// Axes
//const int ZBT_AXIS_X_LINEAR = 0;
//const int ZBT_AXIS_Y_LINEAR = 1;
//const int ZBT_AXIS_Z_LINEAR = 2;
//const int ZBT_AXIS_X_ANGULAR = 3;
//const int ZBT_AXIS_Y_ANGULAR = 4;
//const int ZBT_AXIS_Z_ANGULAR = 5;
// Collision flags
const int ZBT_CF_STATIC_OBJECT= 1;
//const int ZBT_CF_KINEMATIC_OBJECT= 2;
//const int ZBT_CF_NO_CONTACT_RESPONSE = 4;
//const int ZBT_CF_CUSTOM_MATERIAL_CALLBACK = 8;
//const int ZBT_CF_CHARACTER_OBJECT = 16;
//const int ZBT_CF_DISABLE_SPU_COLLISION_PROCESSING = 64;
// Functions
// World
xptr zbtCreateWorld() {}
void zbtDestroyWorld(xptr world) {}
void zbtSetCurrentWorld(xptr world) {}
void zbtSetWorldGravity(float x, float y, float z) {}
void zbtStepSimulation(float timeStep, int maxSubSteps, float fixedTimeStep) {}
// Collision shapes
//xptr zbtCreateStaticPlaneShape(float normalX, float normalY, float normalZ, float planeConstant) {}
xptr zbtCreateBoxShape(float x, float y, float z) {}
xptr zbtCreateSphereShape(float radius) {}
xptr zbtCreateScalableSphereShape(float radius) {}
xptr zbtCreateConeShape(float radius, float height) {}
xptr zbtCreateCylinderShape(float radius, float height) {}
xptr zbtCreateCapsuleShape(float radius, float height) {}
xptr zbtCreateCompoundShape() {}
xptr zbtAddChildShape(xptr compoundShape, xptr childShape, float x, float y, float z, float rx, float ry, float rz) {}
xptr zbtRemoveChildShape(xptr compoundShape, xptr childShape) {}
xptr zbtCreateHeightfieldTerrainShape(xptr heightfieldData, int width, int length, float minHeight, float maxHeight, int upAxis, int bFlipQuadEdges, int bDiamondSubdivision) {}
xptr zbtCreateConvexHullShape(xptr points, int numPoints) {}
xptr zbtCreateMultiSphereShape(xptr positions, xptr radii, int numSpheres) {}
xptr zbtCreateTriangleMeshShape(xptr triangles, int numTriangles, int meshType) {}
void zbtUpdateDeformableTriangleMesh(xptr triangleMeshShape) {}
void zbtSetShapeLocalScaling(xptr shape, float x, float y, float z) {}
//void zbtSetShapeMargin(xptr shape, float margin) {}
//void zbtDeleteShape(xptr shape) {}
void zbtDeleteAllShapes() {}
// Rigid bodies
xptr zbtCreateRigidBodyXYZ(float mass, xptr shape, float x, float y, float z, float rx, float ry, float rz) {}
xptr zbtCreateRigidBody(float mass, xptr shape, xptr position, xptr rotation) {}
void zbtDeleteRigidBody(xptr rigidBody) {}
//void zbtSetMass(xptr rigidBody, float mass) {}
//void zbtSetDamping(xptr rigidBody, float linearDamping, float angularDamping) {}
//void zbtSetLinearFactor(xptr rigidBody, float x, float y, float z) {}
//void zbtSetAngularFactor(xptr rigidBody, float x, float y, float z) {}
//void zbtSetGravity(xptr rigidBody, float x, float y, float z) {}
//void zbtSetLinearVelocity(xptr rigidBody, float x, float y, float z) {}
//void zbtGetLinearVelocity(xptr rigidBody, ref float outX, ref float outY, ref float outZ) {}
//void zbtSetAngularVelocity(xptr rigidBody, float x, float y, float z) {}
//void zbtGetAngularVelocity(xptr rigidBody, ref float outX, ref float outY, ref float outZ) {}
//void zbtApplyCentralImpulse(xptr rigidBody, float x, float y, float z) {}
//void zbtApplyCentralImpulseLocal(xptr rigidBody, float x, float y, float z) {}
//void zbtApplyImpulse(xptr rigidBody, float x, float y, float z, float relX, float relY, float relZ) {}
//void zbtApplyTorque(xptr rigidBody, float x, float y, float z) {}
//void zbtApplyTorqueImpulse(xptr rigidBody, float x, float y, float z) {}
//void zbtApplyTorqueLocal(xptr rigidBody, float x, float y, float z) {}
//void zbtApplyTorqueImpulseLocal(xptr rigidBody, float x, float y, float z) {}
void zbtSetSleepingThresholds(xptr rigidBody, float linear, float angular) {}
// Constraints and limits
//int zbtAreConnected(xptr rigidBodyA, xptr rigidBodyB) {}
//xptr zbtAddFixedConstraint(xptr rigidBodyA, xptr rigidBodyB, float pivotAx, float pivotAy, float pivotAz, float pivotBx, float pivotBy, float pivotBz, float rotAx, float rotAy, float rotAz, float rotBx, float rotBy, float rotBz, int bDisableCollision) {}
//xptr zbtAddPoint2PointConstraint1(xptr rigidBody, float pivotX, float pivotY, float pivotZ) {}
//xptr zbtAddPoint2PointConstraint(xptr rigidBodyA, xptr rigidBodyB, float pivotAx, float pivotAy, float pivotAz, float pivotBx, float pivotBy, float pivotBz, int bDisableCollision) {}
//xptr zbtAddHingeConstraint1(xptr rigidBody, float pivotX, float pivotY, float pivotZ, float axisX, float axisY, float axisZ) {}
//xptr zbtAddHingeConstraint(xptr rigidBodyA, xptr rigidBodyB, float pivotAx, float pivotAy, float pivotAz, float pivotBx, float pivotBy, float pivotBz, float axisAx, float axisAy, float axisAz, float axisBx, float axisBy, float axisBz, int bDisableCollision) {}
//void zbtSetHingeLimits(xptr hinge, float low, float high, float softness, float biasFactor, float relaxationFactor) {}
//void zbtEnableHingeAngularMotor(xptr hinge, int bEnableMotor, float targetVelocity, float maxMotorImpulse) {}
//xptr zbtAddConeTwistConstraint1(xptr rigidBody, float pivotX, float pivotY, float pivotZ, float rotX, float rotY, float rotZ) {}
//xptr zbtAddConeTwistConstraint(xptr rigidBodyA, xptr rigidBodyB, float pivotAx, float pivotAy, float pivotAz, float pivotBx, float pivotBy, float pivotBz, float rotAx, float rotAy, float rotAz, float rotBx, float rotBy, float rotBz, int bDisableCollision) {}
//void zbtSetConeTwistLimits(xptr twist, float swingSpanA, float swingSpanB, float twistSpan, float damping, float softness, float biasFactor, float relaxationFactor) {}
//void zbtEnableConeTwistMotor(xptr twist, int bEnableMotor, float maxMotorImpulse, float targetX, float targetY, float targetZ) {}
//xptr zbtAddSliderConstraint1(xptr rigidBody, float pivotX, float pivotY, float pivotZ, float rotX, float rotY, float rotZ, int bUseLinearReferenceWorldFrame) {}
//xptr zbtAddSliderConstraint(xptr rigidBodyA, xptr rigidBodyB, float pivotAx, float pivotAy, float pivotAz, float pivotBx, float pivotBy, float pivotBz, float rotAx, float rotAy, float rotAz, float rotBx, float rotBy, float rotBz, int bUseLinearReferenceFrameA, int bDisableCollision) {}
//void zbtSetSliderLimits(xptr slider, float linLower, float linUpper, float angLower, float angUpper) {}
//void zbtSetSliderSoftness(xptr slider, float dirLin, float dirAng, float limLin, float limAng, float orthoLin, float orthoAng) {}
//void zbtSetSliderRestitution(xptr slider, float dirLin, float dirAng, float limLin, float limAng, float orthoLin, float orthoAng) {}
//void zbtSetSliderDamping(xptr slider, float dirLin, float dirAng, float limLin, float limAng, float orthoLin, float orthoAng) {}
//void zbtEnableSliderLinearMotor(xptr slider, int bEnableMotor, float targetVelocity, float maxForce) {}
//void zbtEnableSliderAngularMotor(xptr slider, int bEnableMotor, float targetVelocity, float maxForce) {}
//xptr zbtAddGearConstraint(xptr rigidBodyA, xptr rigidBodyB, float axisAx, float axisAy, float axisAz, float axisBx, float axisBy, float axisBz, float ratio) {}
//void zbtSetGearConstraint(xptr gear, float axisAx, float axisAy, float axisAz, float axisBx, float axisBy, float axisBz, float ratio) {}
//xptr zbtAddGeneric6DofConstraint1(xptr rigidBody, float pivotX, float pivotY, float pivotZ, float rotX, float rotY, float rotZ, int bUseLinearReferenceWorldFrame) {}
//xptr zbtAddGeneric6DofConstraint(xptr rigidBodyA, xptr rigidBodyB, float pivotAx, float pivotAy, float pivotAz, float pivotBx, float pivotBy, float pivotBz, float rotAx, float rotAy, float rotAz, float rotBx, float rotBy, float rotBz, int bUseLinearReferenceFrameA, int bDisableCollision) {}
//void zbtSetGeneric6DofLimits(xptr dof, int axis, float lower, float upper) {}
//void zbtSetGeneric6DofLinearLimits(xptr dof, float lowerX, float lowerY, float lowerZ, float upperX, float upperY, float upperZ) {}
//void zbtSetGeneric6DofAngularLimits(xptr dof, float lowerX, float lowerY, float lowerZ, float upperX, float upperY, float upperZ) {}
//xptr zbtAddGeneric6DofSpringConstraint1(xptr rigidBody, float pivotX, float pivotY, float pivotZ, float rotX, float rotY, float rotZ, int bUseLinearReferenceWorldFrame) {}
//xptr zbtAddGeneric6DofSpringConstraint(xptr rigidBodyA, xptr rigidBodyB, float pivotAx, float pivotAy, float pivotAz, float pivotBx, float pivotBy, float pivotBz, float rotAx, float rotAy, float rotAz, float rotBx, float rotBy, float rotBz, int bUseLinearReferenceFrameA, int bDisableCollision) {}
//void zbtSetGeneric6DofSpring(xptr spring, int axis, int bEnableSpring, float stiffness, float damping, float equilibriumPoint) {}
//void zbtSetEnabled(xptr constraint, int bEnabled) {}
//void zbtDeleteConstraint(xptr constraint) {}
// Raycast vehicle
//void zbtSetVehicleTunning(float suspStiffness, float suspCompression, float suspDamping, float maxSuspTravelCm, float maxSuspForce, float frictionSlip) {}
//xptr zbtCreateRaycastVehicle(xptr carChassis, int rightAxis, int upAxis, int forwardAxis) {}
//int zbtAddWheel(xptr vehicle, float connectionPointX, float connectionPointY, float connectionPointZ, float directionX, float directionY, float directionZ, float wheelAxleX, float wheelAxleY, float wheelAxleZ, float wheelRadius, float suspRestLength, int bIsFrontWheel) {}
//void zbtSetWheelIsFront(xptr vehicle, int wheelId, int bIsFront) {}
//void zbtSetWheelRadius(xptr vehicle, int wheelId, float radius) {}
//void zbtSetWheelRollInfluence(xptr vehicle, int wheelId, float rollInfluence) {}
//void zbtSetWheelFrictionSlip(xptr vehicle, int wheelId, float frictionSlip) {}
//void zbtSetWheelSuspRestLength(xptr vehicle, int wheelId, float suspRestLength) {}
//void zbtSetWheelMaxSuspTravel(xptr vehicle, int wheelId, float maxSuspTravel) {}
//void zbtSetWheelSuspStiffness(xptr vehicle, int wheelId, float suspStiffness) {}
//void zbtSetWheelDampingCompression(xptr vehicle, int wheelId, float dampingCompression) {}
//void zbtSetWheelDampingRelaxation(xptr vehicle, int wheelId, float dampingRelaxation) {}
//void zbtSetWheelSteering(xptr vehicle, int wheelId, float steering) {}
//void zbtSetWheelEngineForce(xptr vehicle, int wheelId, float force) {}
//void zbtSetWheelBrake(xptr vehicle, int wheelId, float brake) {}
//void zbtResetVehicleSusp(xptr vehicle) {}
//float zbtGetVehicleCurrentSpeed(xptr vehicle) {}
//void zbtGetWheelPositionXYZ(xptr vehicle, int wheelId, ref float outX, ref float outY, ref float outZ) {}
//void zbtGetWheelPosition(xptr vehicle, int wheelId, xptr outPosition) {}
//void zbtGetWheelRotationXYZ(xptr vehicle, int wheelId, ref float outRx, ref float outRy, ref float outRz) {}
//void zbtGetWheelRotation(xptr vehicle, int wheelId, xptr outRotation) {}
//void zbtGetWheelPosRotXYZ(xptr vehicle, int wheelId, ref float outX, ref float outY, ref float outZ, ref float outRx, ref float outRy, ref float outRz) {}
//void zbtGetWheelPosRot(xptr vehicle, int wheelId, xptr outPosition, xptr outRotation) {}
//void zbtDeleteRaycastVehicle(xptr vehicle) {}
// Ghost object
//xptr zbtCreateGhostObject(xptr shape, float x, float y, float z, float rx, float ry, float rz) {}
//void zbtDeleteGhostObject(xptr ghostObject) {}
//int zbtGetNumOverlappingObjects(xptr ghostObject) {}
//xptr zbtGetOverlappingObject(xptr ghostObject, int index) {}
// Kinematic character controller
//xptr zbtCreateKinematicCharacterController(xptr ghostObject, float stepHeight) {}
//void zbtDeleteKinematicCharacterController(xptr controller) {}
//void zbtSetCharacterUp(xptr controller, float x, float y, float z) {}
//void zbtSetCharacterWalkDirection(xptr controller, float x, float y, float z) {}
//void zbtSetCharacterVelocityForTimeInterval(xptr controller, float x, float y, float z, float timeInterval) {}
//void zbtCharacterWarp(xptr controller, float x, float y, float z) {}
//void zbtSetCharacterFallSpeed(xptr controller, float fallSpeed) {}
//void zbtSetCharacterJumpSpeed(xptr controller, float jumpSpeed) {}
//void zbtSetCharacterMaxJumpHeight(xptr controller, float maxJumpHeight) {}
//int zbtCharacterCanJump(xptr controller) {}
//void zbtCharacterJump(xptr controller) {}
//void zbtSetCharacterGravity(xptr controller, float x, float y, float z) {}
//void zbtSetCharacterMaxSlope(xptr controller, float slope) {}
//void zbtSetCharacterUseGhostSweepTest(xptr controller, int bUseGhostObjectSweepTest) {}
//int zbtCharacterOnGround(xptr controller) {}
//void zbtCharacterReset(xptr controller) {}
//void zbtSetCharacterUpInterpolate(xptr controller, int bInterpolate) {}
// Collision objects (in general)
//void zbtSetFriction(xptr obj, float friction) {}
//void zbtSetRollingFriction(xptr obj, float friction) {}
//void zbtSetRestitution(xptr obj, float restitution) {}
//void zbtSetHitFraction(xptr obj, float hitFraction) {}
void zbtGetPositionXYZ(xptr obj, ref float outX, ref float outY, ref float outZ) {}
//void zbtGetPosition(xptr obj, xptr outPosition) {}
void zbtSetPositionXYZ(xptr obj, float x, float y, float z) {}
void zbtSetPosition(xptr obj, xptr position) {}
//void zbtGetRotationXYZ(xptr obj, ref float outRx, ref float outRy, ref float outRz) {}
//void zbtGetRotation(xptr obj, xptr outRotation) {}
//void zbtSetRotationXYZ(xptr obj, float rx, float ry, float rz) {}
//void zbtSetRotation(xptr obj, xptr rotation) {}
//void zbtGetRotationQuat(xptr obj, xptr outQuaternion) {}
//void zbtGetRotationDirection(xptr obj, xptr outDirection) {}
//void zbtSetRotationDirectionXYZ(xptr obj, float x, float y, float z) {}
//void zbtSetRotationDirection(xptr obj, xptr direction) {}
void zbtGetPosRotXYZ(xptr obj, ref float outX, ref float outY, ref float outZ, ref float outRx, ref float outRy, ref float outRz) {}
//void zbtGetPosRot(xptr obj, xptr outPosition, xptr outRotation) {}
//void zbtSetPosRotXYZ(xptr obj, float x, float y, float z, float rx, float ry, float rz) {}
void zbtSetPosRot(xptr obj, xptr position, xptr rotation) {}
//void zbtGetModelMatrix(xptr obj, xptr outMatrix) {}
//void zbtGetModelMatrixInv(xptr obj, xptr outMatrix) {}
void zbtSetCollisionFlags(xptr obj, int flags) {}
//int zbtIsActive(xptr obj) {}
//void zbtActivate(xptr obj, int bForceActivation) {}
void zbtSetActivationState(xptr obj, int newState) {}
//void zbtForceActivationState(xptr obj, int newState) {}
//void zbtSetDeactivationTime(xptr obj, float time) {}
//void zbtSetUserIndex(xptr obj, int index) {}
//int zbtGetUserIndex(xptr obj) {}
void zbtSetUserModel(xptr obj, model userModel) {}
model zbtGetUserModel(xptr obj) {}
// Collision detection
//void zbtSetIgnoreCollisionCheck(xptr objA, xptr objB, int bIgnoreCollisionCheck) {}
void zbtSetCollisionFilterGroupAndMask(xptr obj, int group, int mask) {}
//int zbtStartCollisionDetection() {}
//int zbtGetNextContact(ref xptr outObjA, ref xptr outObjB, xptr outPosA, xptr outPosB, xptr outNormal) {}
//void zbtGetCollidedObjects(int contactIndex, ref xptr outObjA, ref xptr outObjB, ref float outAppliedImpulse) {}
int zbtIsColliding(xptr obj) {}
//int zbtGetNumberOfCollisions(xptr obj) {}
int zbtIsCollidedWith(xptr objA, xptr objB) {}
//float zbtGetCollisionImpulse(xptr obj) {}
xptr zbtGetMainCollidedObject(xptr obj) {}
// Raycasting
xptr zbtRayTest(float fromX, float fromY, float fromZ, float toX, float toY, float toZ) {}
xptr zbtRayTestFiltered(float fromX, float fromY, float fromZ, float toX, float toY, float toZ, int filterGroup, int filterMask) {}
void zbtGetRayTestHitPointXYZ(ref float outX, ref float outY, ref float outZ) {}
//void zbtGetRayTestHitPoint(xptr outPosition) {}
//void zbtGetRayTestHitNormalXYZ(ref float outX, ref float outY, ref float outZ) {}
//void zbtGetRayTestHitNormal(xptr outNormal) {}]]>
</Source>
</ZExternalLibrary>
<ZLibrary Comment="Google Doc - DATA" HasInitializer="1">
<Source>
<![CDATA[/*
In the real project, I have a shitload of models.
So everything is listed in a Google Sheet doc where I can check if they are listed in the database,
set their names...and then export this list.
*/
const int
M_PLANE=0,
M_PYRAMID=1,
M_TRUNK=2,
M_BUILDING=3;
{
DB_List.SizeDim1=4;
DB_List[0]=M_PYRAMID;
DB_List[1]=M_TRUNK;
DB_List[2]=M_BUILDING;
DB_List[3]=M_PLANE;
}]]>
</Source>
</ZLibrary>
<ZLibrary Comment="Body Shapes">
<Source>
<![CDATA[const float
CAM_FOV = 0.4142; // = tan(App.FOV(45) / 360 * PI);
/*
We need to create all the collision shapes here
*/
xptr
World,
Shape_Sphere,
Shape_Pyramid,
Shape_Trunk,
Shape_Building,
Shape_Plane;
vec3 BodyShape(int type)
{
switch(type)
{
case M_PLANE: return vector3(1.0, 0.8, 0.9);
case M_PYRAMID: return vector3(5.5, 4.0, 5.5);
case M_TRUNK: return vector3(0.5, 1.5, 0.5);
case M_BUILDING: return vector3(1.0, 2.5, 2.0);
}
// Or return no scale
return vector3(1.0, 1.0, 1.0);
}
xptr CreateRigidBody(model object, int type)
{
switch(type)
{
case M_PLANE: return zbtCreateRigidBody(1, Shape_Plane, object.Position, object.Rotation);
case M_PYRAMID: return zbtCreateRigidBody(1, Shape_Pyramid, object.Position, object.Rotation);
case M_TRUNK: return zbtCreateRigidBody(1, Shape_Trunk, object.Position, object.Rotation);
case M_BUILDING: return zbtCreateRigidBody(1, Shape_Building, object.Position, object.Rotation);;
}
trace("\nThere is a problem with CreateRigidBody type=" + intToStr(type) + "\n");
return zbtCreateRigidBody(1, Shape_Sphere, object.Position, object.Rotation);
}
void RenderMesh(int mesh)
{
switch(mesh)
{
case M_PLANE: @RenderMesh(Mesh:Mesh_Plane); return;
case M_PYRAMID: @RenderMesh(Mesh:Mesh_Pyramid); return;
case M_TRUNK: @RenderMesh(Mesh:Mesh_Trunk); return;
case M_BUILDING: @RenderMesh(Mesh:Mesh_Building); return;
}
}
/*
Set the visible collision Mesh, that has no collision at all...
*/
void UpdateCollisionMesh()
{
if (Database_Body != null) zbtDeleteRigidBody(Database_Body);
DatabaseTransformCollision.Scale = 1;
DatabaseTransformCollision.Translate = 0;
DatabaseTransformCollision.Rotate = 0;
int CurrentView = DB_List[MenuData];
switch (CurrentView)
{
case M_BUILDING: DatabaseCollisionMesh.Mesh = Mesh_Cube; break;
case M_PLANE: DatabaseCollisionMesh.Mesh = Mesh_ShipCollision; break;
case M_TRUNK: DatabaseCollisionMesh.Mesh = Mesh_ColCylinder; break;
case M_PYRAMID: DatabaseCollisionMesh.Mesh = Mesh_Cone; break;
}
DatabaseTransformCollision.Scale = BodyShape(CurrentView);
// Set the Body, that has the real collision, but is not visible
Database_Body = CreateRigidBody(ModelViewer, CurrentView);
}]]>
</Source>
</ZLibrary>
<ZExpression Comment="init physics">
<Expression>
<![CDATA[// Init physical world
World = zbtCreateWorld();
zbtSetCurrentWorld(World);
zbtSetWorldGravity(0, 0, 0);
// Create collision shapes
// Details about shapes: https://stephengold.github.io/Minie/minie/minie-library-tutorials/shape.html
// or https://docs.panda3d.org/1.10/python/programming/physics/bullet/collision-shapes
//--- BASIC SHAPES -------------------------------------------------------------
// BOX: zbtCreateBoxShape(float x, float y, float z)
// size x,y,z is from center, so the final size will be x2...
Shape_Building = zbtCreateBoxShape(1.0, 2.5, 2.0);
// CONE: zbtCreateConeShape(float radius, float height)
Shape_Pyramid = zbtCreateConeShape(2.75, 4.0);
// CYLINDER: zbtCreateCylinderShape(float radius, float height)
Shape_Trunk = zbtCreateCylinderShape(0.5, 1.5);
// SPHERE: zbtCreateSphereShape(float radius)
Shape_Sphere = zbtCreateSphereShape(1.0);
//--- COMBINED SHAPES ----------------------------------------------------------
xptr Plane_Hull_Shape = zbtCreateScalableSphereShape(1);
zbtSetShapeLocalScaling(Plane_Hull_Shape, 0.6, 0.3, 2.6);
xptr Plane_Wing_Shape = zbtCreateScalableSphereShape(1);
zbtSetShapeLocalScaling(Plane_Wing_Shape, 0.9, 0.1, 0.2);
xptr Plane_Left_Wing_Shape = zbtCreateCompoundShape();
zbtAddChildShape(Plane_Left_Wing_Shape, Plane_Wing_Shape, -1.3,-0.1,1.0, 0.1,0.6,0.03);
xptr Plane_Right_Wing_Shape = zbtCreateCompoundShape();
zbtAddChildShape(Plane_Right_Wing_Shape, Plane_Wing_Shape, 1.3,-0.1,1.0, -0.1,0.6,-0.53);
Shape_Plane = zbtCreateCompoundShape();
zbtAddChildShape(Shape_Plane, Plane_Hull_Shape, 0.0,0.05,-0.8, 0.0,0.0,0.0);
zbtAddChildShape(Shape_Plane, Plane_Left_Wing_Shape, 0.0,0.0,0.0, 0.0,0.0,0.0);
zbtAddChildShape(Shape_Plane, Plane_Right_Wing_Shape, 0.0,0.0,0.0, 0.0,0.0,0.0);]]>
</Expression>
</ZExpression>
<SpawnModel Model="ModelViewer" Position="0 0 -8" SpawnStyle="1"/>
<ZExpression>
<Expression>
<![CDATA[MenuData = 0;
Database_Body = null;
UpdateCollisionMesh();]]>
</Expression>
</ZExpression>
</OnLoaded>
<OnUpdate>
<ZExpression Comment="Mouse raycast">
<Expression>
<![CDATA[Axis[0,0] = 0;
Axis[1,0] = 0;
zbtStepSimulation(App.DeltaTime, 0, 0);
// Mouse Raycast
float z = App.CameraPosition.Z - ModelViewer.Position.Z;
float x = z * App.MousePosition.X * CAM_FOV * App.ViewportWidth / App.ViewportHeight;
float y = z * App.MousePosition.Y * CAM_FOV;
Transform_MouseToRay.Translate.X = x;
Transform_MouseToRay.Translate.Y = y;
if (zbtRayTest(x, y, App.CameraPosition.Z, x, y, -1000) != null) // The body has been hit by the ray
{
vec3 pos;
zbtGetRayTestHitPointXYZ(pos.X, pos.Y, pos.Z); // Set collision point coordinates to pos
Transform_MouseToRay.Translate.Z = pos.Z;
MouseToRaySize.Scale = 0.004 * (App.CameraPosition.Z - pos.Z); // Set the size of the ball at the tip of the ray, where the collision happens
DatabaseCollisionColor.Color = vector4(1,0,0,0.6); // Red
}
else
{
Transform_MouseToRay.Translate.Z = -200;
MouseToRaySize.Scale = 0;
DatabaseCollisionColor.Color = vector4(1,1,1,0.2); // White
}]]>
</Expression>
</ZExpression>
<KeyPress Comment="Left" Keys="<QA">
<OnPressed>
<ZExpression Expression="Axis[0,0] = -1;"/>
</OnPressed>
</KeyPress>
<KeyPress Comment="Right" Keys=">D">
<OnPressed>
<ZExpression Expression="Axis[0,0] = 1;"/>
</OnPressed>
</KeyPress>
<KeyPress Comment="Up" Keys="^ZW">
<OnPressed>
<ZExpression Expression="Axis[1,0] = 1;"/>
</OnPressed>
</KeyPress>
<KeyPress Comment="Down" Keys="_S">
<OnPressed>
<ZExpression Expression="Axis[1,0] = -1;"/>
</OnPressed>
</KeyPress>
<KeyPress Comment="Space" CharCode="32" RepeatDelay="0.2">
<OnPressed>
<ZExpression>
<Expression>
<![CDATA[MenuData += 1;
if(MenuData == DB_List.SizeDim1) MenuData = 0;
UpdateCollisionMesh();]]>
</Expression>
</ZExpression>
</OnPressed>
</KeyPress>
</OnUpdate>
<OnRender>
<RenderTransformGroup Name="Transform_MouseToRay" Translate="-28.3807 7.4556 -200">
<Children>
<UseMaterial Material="DatabaseRayMaterial"/>
<RenderMesh Mesh="Mesh_DatabaseRay"/>
<RenderTransformGroup Name="MouseToRaySize" Scale="0 0 0">
<Children>
<RenderMesh Mesh="Mesh_Sphere"/>
</Children>
</RenderTransformGroup>
</Children>
</RenderTransformGroup>
</OnRender>
<Content>
<Model Name="ModelViewer" Position="0 0 -8" Rotation="0.0892 0.1715 0" RotationVelocity="0.0004 0.0008 0">
<OnSpawn>
<ZExpression>
<Expression>
<![CDATA[// Init ModelViewer position and rotation
CurrentModel.Position.X = 0;
CurrentModel.Position.Y = 0;
CurrentModel.Position.Z = -8;
CurrentModel.Rotation = 0;
CurrentModel.RotationVelocity = vector3(rnd(), rnd(), 0);]]>
</Expression>
</ZExpression>
</OnSpawn>
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[// Rotate the model with arrow keys or decelerate rotation if not
if(Axis[1,0] && abs(CurrentModel.RotationVelocity.X) < 0.4) CurrentModel.RotationVelocity.X -= 0.5 * Axis[1,0] * App.DeltaTime;
else CurrentModel.RotationVelocity.X += 0 - App.DeltaTime * CurrentModel.RotationVelocity.X;
if(Axis[0,0] && abs(CurrentModel.RotationVelocity.Y) < 0.4) CurrentModel.RotationVelocity.Y += 0.5 * Axis[0,0] * App.DeltaTime;
else CurrentModel.RotationVelocity.Y += 0 - App.DeltaTime * CurrentModel.RotationVelocity.Y;
// Set the Collision Body to the current rotation of the model
zbtSetPosRot(Database_Body, CurrentModel.Position, CurrentModel.Rotation);]]>
</Expression>
</ZExpression>
</OnUpdate>
<OnRender>
<UseMaterial Material="GhostMaterial"/>
<ZExpression Comment="Render Mesh">
<Expression>
<![CDATA[// I do it that way, because I use the same RenderMesh function to render things within the game too
int mesh = DB_List[MenuData];
RenderMesh(mesh);]]>
</Expression>
</ZExpression>
<RenderTransformGroup Name="DatabaseTransformCollision">
<Children>
<RenderSetColor Name="DatabaseCollisionColor" Color="1 1 1 0.5"/>
<RenderMesh Name="DatabaseCollisionMesh" Mesh="Mesh_ShipCollision"/>
</Children>
</RenderTransformGroup>
</OnRender>
</Model>
<Array Name="DB_List" Type="1" SizeDim1="4"/>
<Variable Name="MenuData" Type="1"/>
<Variable Name="Database_Body" Type="9"/>
<Group Comment="Materials">
<Children>
<Material Name="GhostMaterial" Shading="1" Color="1 1 1 0.2" SpecularColor="0 0 0 1" EmissionColor="0 0 0 1" Blend="1" ZBuffer="0"/>
<Material Name="DatabaseRayMaterial" Shading="1" Color="1 0 0.502 1" Light="0" SpecularColor="1 1 1 1" EmissionColor="1 0.502 1 1" Shininess="1"/>
</Children>
</Group>
<Group Comment="Meshes">
<Children>
<Mesh Name="Mesh_Trunk">
<Producers>
<MeshImport HasVertexColors="1">
<MeshData>
<![CDATA[789CED983F6B9CCB1587C7B65204EE1606072EB752A3E54A95903E40E63B683B23175B48626AB5C242DDE20F2009D248A8122AB7573E8084AA354881B8BC315C9C2E8108FC669EF3EC78951B1CECC4E63AB02FEC683C7FCEF99DDF3967E68CDF3E49E90F8F13DF654A7FBCF4EFFEEF53CA99BF9B0BE72B6F5EF49FD6F1BCB99012FDF39594DFBC385FA9FFAE6BEA5C3E5FE93F7DF322A5CD0567F79652DA5B72D7DED2F9CADE12230777CC76978C77978C1FDC7555DBEDBBC593F395D3FBC593944EEFBBCBF395DB770777EC62B6FF9491FED3833B64DA67E5E602BB36175CE38818D27ED893DD4B2B1E2588EAF6DDCCA2D37B5AB6742FBB8E9691C51366174F44CB7A306305721A72B4801FE4C8A83BABF6AE3BBD87B79934FAD5F69729D1AA578D32ACBDA212E7ED3B98945BF1CBE4D4AE9026CEA6E57C65F1C456B4CE22A7BB94AB2933FB55726A1C8AB9AEE944AE2F9A8DF8424B417870272A2D12AD966205B2B428A48734E264C64C6809C6F4BE7C62639515A8F4E034BA02AD31F3D017EA9ACA746FC86CBAD8DBEC45A61C1A397228DBCC6EF56F76CE5776978DDBF58DF395EDB5B3BAFE2CEB97EDB5F395F58DDDE5F3959B1D7DB7D5D78360607CF590355717E264EFF34BE41C5D6B23F25FBD46D7F1EDEA21BAE4F0EA025DCF2FD1258747D7E87AF51A5DFAF7F8562FA38BF1D543D65C5DE853F63EBF44CED1B5DE417ED595F51AAD9CE853F977AFFE354EDC5B5796C8E81C195D22A3736474898CCE913B3932BAC05ECAE1DF12FECD21BF1045757D72EF54E6BEFEA9B3E8CDA13787DEC2BFC94664463CE4888702F290197DD7A88B5D9129D9B59129C57E446C8988CD11B12522B62829223647C496C8C7121994238372F05C22834A64508E0CCA91412532E8832DDA58639C1324B8929F2933C121B3334EE00A0971BE1567234A4B9C6059097142963821739C9085D30699AE71AF566BA332D5A5EDCD3A2DC26A2DAD115BE224CFA28E93BC20158D8C447EE5C8AFC2E9474BF6444667FACA61AFD22AD31D7E1C4CE07930A1DF750777154B076F8C9CDE0F26F4590916ACA64DFB9C5BF0825DB4D5A68EDCA4E584C33EDACA50C7294DCB99C2294DCB38FEA2653DA7342D72E08D16F9C4032DDAE18A16EDAC45EFE2C960D2507597830923221C4CF035385D231E2CC2F63A9BA7A8B2F807136200FC2923478429551E2A5A7810BF32DFBC40A69CA84BE4FDA7F08634FAA0441A39C2ACE3DA85047C4CDF35DA28AAAE43AF68654C6922518B08E55C8BF0267D2C755C4EE4CA59A5E9D9A60539482636D06E54C83C12C8C7F048B554749C1B813F7C01C3ADEF1A3D6524C82D9823F62B2AB538A25E574EF90CFEF58B3C8B4199EA129B16AD1E0E26BBCBE8DDEACBC3D5C560C2F93C989C4D3D7E743D98703E0F269CCF587D7CDB18E67C1E4C389F0713CE67B8652FE7F360C2F90C1B68E12E184C8E6F8D28B14D232DCB33ADF6DEEC804A1BD737C07396C1A3BDDB6BE0D95D068F31B6D59F451AE3DC4DE0D1D7ECE56E028F5184FC57AF65C6F89199E617BC2086F58DDE787B4D0C373BBD3123E2E98DCFB2A85C232AC7B7D77A63FACC5E5DF4C647D732B07AD81BBF7A2D33CF2F7BE3C6926B66BC6DAFB1727759EF30BBBD26FFC7B7BD71F7F2D5EBDE983E562B536ED37E6FCC6D8B2E3DA296A3EBDE983EF2F5AC329BAFC1DC22A137DEEA1B0F6268FE45027A9BAFD5EE4843D556B66811A7F1A35E67D5E8B8DE81B1AB0BD8A38F7CDBDD65E43BAB67C5A62FF491981979F55A2FE391A36BBD6C5F2DCA778D5CB9C6BD72A896AD3E16A9DDE8B265E466A7CD62A3AD1E77D648B00668B727F7A637A6779937A6771CB3518F95A8C74AD46325EAB112F558897AAC443D56A21E2B518F4D6FB7A8C74AD46325EAB112F558897AAC443D56A21E2B518F95A8C74AD46325EAB112F558399B5608B5D62A518F95A8C74AD463A5D5098C473D56A21E2B518F95A8C74AD46325EAB112F558D4245635DED7B4D6065BFDE1080ED1A22DBBCBC3D1CDCEFAC670D46C3FCBC3D1D9940DE5AF1E0E47E411F2AF2E86237CCD382B9F7FB09A71A4E13B2583598D373BC311598C4C75C93C9289257C91F68723E29FF1C606D8E4E4E87A385ADF403B793ADB2B93C7B768912579632F8C0D47E4200865EFF92598B7D790A6BD7A59AB1927E6679ED522597A180F4A685EC076B9527ED38E84E63B24CB9892E54D8DDA2E27722527482367D16BB4C883E3DA2E27CE1A694820BF8CBDE1E8F856261B33E09731D7E83B7DEADE692CC5DE16BD8C5B0DD6F320833065EE2F6ABC6A410643CA67D3EAB7E67AC6832913CFD47555526E3530E370C24EAB5FF6C264CAC433D5005AC09032F797157E549356C5D91AB555B3DC5FA0B2E65CDF004FE5239F4DEBCFED35462BEA4C2E83A446DC876A93713C0E1EEB52F612D5E0B15A463EF757BCE7B3F53035597B8F70FF6BAF2F29DF565AAD7C5F73BEE3D4EEDB4D5DED35874699F1CDE52B4C7EDAAB0D2DCA9767DF7DEE55A668D5EE6BAEA10289FEF285A837DB0B11C6EC379FF266943DDFAABE52E556CE7DC9CAB92FDCE65F90B7B72416F97ED4B3BE1FF5F8F42D19BE6EAF57D6E891872FDFC6A4ACC24063154E64D295F2A904ED923D2D92376358CCDAE23B5D690FDFE332D0E20A0932A0ED6296F3F606C7969629C854979CB7D734B6CB89FEBD7D57EFB8FAAE198E78E3D40CADFDDE98F7726FCCBD46CB1D4A04F7C6C43FEDDE526FCCBD463BBB97C985BA725A2959236D2EF4C6E4C2ECDE4C895BF5E1CDCB9AC5136F7F24741F6E70EE7474910BDEDD563EE802799A5638561AA7F7E86A9509BABA0E2DB36A6AF590358B27D639DADE2A347469FBB4D6AA18B8D76861837B8D160CBC338623F2D1F1E1887ADB95F4DD9B326BDC6B5F5BF69660DB35E291F9D3FBE188FECC23CA5497D8D425064E4BDE11C8673DE7A42739673B32E1C7B39AD31BF9F0C379EEF9DC759CC99ECC6A7F788B89CAFBC51B47549ECC9ED5E0E19CA4658438198E88135A2CE59C0455FF2978DABD0F9ECD05F078AF79DFA504126F70663927C1E39D850462033CDE2032E90D224BF22C4B535F044BC698F2956C1C1A6F8E28DF957ACA11B5CC56F20624D2CC0B6D375F64A0654DB0116B64C97C9119F348AFD9778D7B5D633CEB237D673C9B65722BABE6A319EA781B41CE145BF45D33F317AF4CE2A771455C99596A348A44227E4744EE4A51193F0D2D1CCA9208E54DE4293D4A8FEBAFEB1EA527E937F5F765FBFC87FFA3FA5B48B3FEE34FECD3439A7F1D7FF21FD63C94F0B86AFCD2B67C5EFFAE03C3F21790A9D5FF6EE3A37F6166E117E30FB9FA187B9FBEFE5DF7A4F69EA59FBB9F2BA267E9771FE5FF631EF9D4F57FED52FDBDAFEDFBEE591D79F68DFAF7DBEEC3CFFB8EFEC22771F5B118FBDAFDFF173FFEB9F278D72DA53F753F56CC3F7E555D0F7DF13572F921E7BF3C9F7FAA79F797EE71C8FCBEB6DF7F76FE7EEEFAB755E3DB69BEFF50477E98E7FBFCBEF88CF899DF17F3F3677EFE7CABFDAF71167D6E04FE2F67D1E745D7AF7716CD73F6BFE3F91FB5AEFB5BF7DBF4F7EEBBBAFEBB5F3D5F3ED6EFE6DFFC9B7FF36FFECDBFF937FFE6DFFC9B7FF36FFECDBFF9F74D7CFF0421898BCC]]>
</MeshData>
</MeshImport>
</Producers>
</Mesh>
<Mesh Name="Mesh_Pyramid">
<Producers>
<MeshImport HasVertexColors="1">
<MeshData>
<![CDATA[789CED51B191C2400C5CFCF01145B8063C43EC329E8C8836B836889CD1865D80A981223EFCF9172BE974F6CC270C0C19E739495E492B9DF405600B3DED4031B81E5A20B5A693392945DC329D4C27ECA5A775945E3A95D83BE25E39A2DD7CA306592E6B958AC89598DAD7402E6B95A895E17056D4F024FD6917FCC48D7942A43B9CCDEE02A1CF7AD0DC71749EA699D888A9DD07D2342AD95146B48A476666EB2A6745B7252BC794DCD3AED46296BF7A8A274B3D4D204716CE7174DC6BC51BB54A4C43F963AA36EDF26ACEDCF12E7AE6AC6D533E73DF60DE85EFD2B639F7E68DD866F3468A4D9FC57B0CB040C52BB2C00756BCF3CFF10A1A052C29FFA4C2AFACF0C30B7CF21FBC4274C9BF39CF63B9CFD47ADEFEFFF67B72E57D5E7A6E7B3B92D7]]>
</MeshData>
</MeshImport>
</Producers>
</Mesh>
<Mesh Name="Mesh_Plane">
<Producers>
<MeshImport HasVertexColors="1">
<MeshData>
<![CDATA[789CDD4FB10DC23010BC3801092A4449C1082051D1E10118222BB081178884C400D904D2D1241D4C105150D222C8F3FE77424A6ADEF2CB3EDF9DEF570066902AAAB23C02930270B62AB71B606FE90497D5704056F3D9F79C724652E0BCF3322258E128224C46A02A45B8B8D76BE632BFF5E939A4E26983D675BDF50F6EDE87E87ED00CC141F080485AC5434E55A9BF6A95A319348F765575F37A95F8A7BD79C3A4FAFBD7337010C1F0268A1063C05B972206FE1D481005DCA0A117BD29E6F7863334D2877C7B92C118233CC86BA7CC4C3AB7DFD78D2E74A5399658C894FF501F4EDF7856]]>
</MeshData>
</MeshImport>
</Producers>
</Mesh>
<Mesh Name="Mesh_Building">
<Producers>
<MeshImport HasVertexColors="1">
<MeshData>
<![CDATA[789CED53BB4EC340105C830DE1D9A21408241A1054F448EE43CF1FA4A2E0135CF305B8434AFE800F081D4D6A40502252D20404029265E7C6CB3914D052E424AFC7B30FEFCDDE7544E458B08A9EC8E6A5013CB9C8B93D45AE2AD57284B77E2FE093B3FD0BD87E5FB5DBA205E371867BF6559425B014AAFD436029C4EA2FDC8099AC89AFFE21BDC82577DDD19EF771DDB16C3938855D3CAAAC757CB355D9C2FB3E38451656B765F113FBE8B6AC8E9C9CD1D21B7BF1D8D857D9C47FCB266A02C3A287F6807D62A7ED01F70B063CBCDCB57BC930DEBDAC409E5965133B2A9BD84BC045C039F9FAAEDD1B156024BDED019587E6ED812B5F96AC5C578C5988F12CC6034B8EF9EE0D31D9BD21260E0C26AA77B50C0C0B25A12DF1D53294AF7BC970221ECF3ACC8A7389918EDDCB59F00C700A3C15CEF3B43843CC79014F4E900CABF94CA9704DA56A0A51496A456D25A732F5F34F7D5CA5783BA8A4DB7877A82A19AF462F306F8A9F13DE1A9E3A4CC7E7C53BC58993E73DF29962D689CCD8A39AC86CC023C53B13789260DF3533BE216FFA69510DC3B805C0A92C54B949158DDCD418AF93DA1B799945CE99FF43C7E69BB7B891BE847F6681E5FD4AE5591BF2A42B32D435E3574347B193BA7DD439F3ADCB8332E6D52A6F583DB17E93F067F6F961FFCB64A9EA931DCE860A63EB70C6E23EF53DEC250DF1E380E7BF35C942C64F7CAFA8BF2DB77A67F57765E78FF829FE1DEB744DD73F595F5837EEC6]]>
</MeshData>
</MeshImport>
</Producers>
</Mesh>
<Mesh Name="Mesh_DatabaseRay">
<Producers>
<MeshBox/>
<MeshTransform Scale="0.008 0.008 200" Position="0 0 200"/>
</Producers>
</Mesh>
</Children>
</Group>
<Group Comment="Collision Meshes">
<Children>
<Mesh Name="Mesh_Cone">
<Producers>
<MeshSphere Scale="0.5 0.5 0.5" ZSamples="3" RadialSamples="18"/>
<MeshTransform Rotation="0.25 0 0"/>
<MeshExpression Expression="v.Y = v.Y < 0.25 ? -0.5 : 0.5;"/>
</Producers>
</Mesh>
<Mesh Name="Mesh_ShipCollision">
<Producers>
<MeshLoad Comment="hull" Mesh="Mesh_Sphere"/>
<MeshTransform Scale="0.6 0.3 2.6" Position="0 0.05 -0.8"/>
<MeshLoad Comment="left" Mesh="Mesh_Sphere"/>
<MeshTransform Scale="0.9 0.1 0.2" Position="-1.3 -0.1 1" Rotation="0.1 0.6 0.03"/>
<MeshCombine/>
<MeshLoad Comment="right" Mesh="Mesh_Sphere"/>
<MeshTransform Scale="0.9 0.1 0.2" Position="1.3 -0.1 1" Rotation="-0.1 0.6 -0.53"/>
<MeshCombine/>
</Producers>
</Mesh>
<Mesh Name="Mesh_Sphere">
<Producers>
<MeshBox Scale="1 0.5 1" XCount="18" YCount="12" Grid2DOnly="255"/>
<MeshExpression AutoNormals="0">
<Expression>
<![CDATA[//
float E, A, K, X, Y, Z;
// Convert range to radians
E = v.Y*PI; // Elevation
A = v.X*PI; // Azimuth
// Convert spherical coordinates into cartesian
K = cos(E);
X = sin(A)*K;
Y = sin(E);
Z = cos(A)*K;
// Assign coordinates
v.X = X;
v.Y = Y;
v.Z = Z;
n.X = X;
n.Y = Y;
n.Z = Z;]]>
</Expression>
</MeshExpression>
</Producers>
</Mesh>
<Mesh Name="Mesh_Cube">
<Producers>
<MeshBox/>
</Producers>
</Mesh>
<Mesh Name="Mesh_Capsule">
<Producers>
<MeshImport HasVertexColors="1">
<MeshData>
<![CDATA[789CED98ED4B546918879F7658778B5928E8834D6EE8088531156105C74D1ADC6485C0A52FAE51484E1FA4C43E682146EB0B95DBA64265854B4C22B699B1042D428B610349274A096AA0371C0B6CF2434BC10E06C2B067FBCD3553F30F2CBBD039E1C3CD75FF9C79CE7D859CF3ACF018737881315FE43B37A79DB6C85CF0EF9B5FE6B76D99769C2D73C1D62D55D57634E135ED4EC4986D554E249963DAEDE8F739F31BECE8AA7C48DE7A27B2663949F8A1A54E644FC9D8323BFAB8942E75ABC78994D69E5B6847EF85C86CCDB1A3A60B6E8C1339D645B770B11DFDFA7748ED2227F2EB08C9829576F46514D251E044563F2139556E477FFB13325DE644ACBF48C6EBEDA83D0F99DAE7441C87A4EF8C38A4F0AC569285A3EA420AC6F45B24A79FEAD320ADD3A9EF4D252FCC692774E1536FB51FC7D1CEA9C9DC98D7FE3B92BA536A327BDFE97EE165AFECE8A352C8B1D79A0F6BCE84A64A77E6BEE6393CA469538F0CCB0219EC40B046B2AC261CFF7605DD8CD3703C9CBB26188EFFB236DB1D4938D63C45E1F8B3EFE852E3A87C79385E5147A631371CFFF16738A6E83EC90FC76F5D81608A644F7138DE7A078229925D95E178EF14045324E3FBC3F13F66219822E93B250EC114C903D752DD331F9D926C9C4C7D6F8A608D24A6E8C2573DD77E30454DA66756FBC7113599D197BA5F78F291A604C11AEBC388A64A175F63039A3635A6C8600782359287EBECC43716DD0F4E13F91B07B6DB8965E5D9EE484E06ED44E30F10DC917CB0C94E54EC87608AE4F8063BE1FF09822992D8A10B8F95D889CA7EEC509339586127D68D60879ACC925D76A27D1C3BD4647A9BEC44DF4443B756BA988253BF19549E0CBE584F5CD7E7D3C51DABFFB6F6431777AC9B27B47FBAB8C3111CB2F6AEEE971553C5114D8624358E6AAE6A9264A87174A44F9327438D2F4C91C96B8A2537ED8460CA698B25BFDAD15F174B36D5423045D2AE892573EB219822D9B92396F435433045B2B13A965C7D1482359298A20B1FDA194BBE3889296A3293A158F2D9794C5193C96B88256707B1434DA6B925962CBA8C236A32C73B3FF299D3CA43B0C65A1CD6E7D3C51A6BF545ED872ED6D2EE86B47FBA69772982B5964BBA533835D6AC014D860C35D676F7699264A8B136D3ADC993A1C617A6C850E3C869739C17EDAC101C41A8B103A1C60B841A3B106ABC40A83102A1C645FADB53351698361CC29C21749930842EB385D065C210BA10260CA766B6106AA60AA1669EE96F4CD79A6466867E8F6A633449BF475DD5FD757E4F536D36B16BFC9EDC7A38A47387DFE36B86431AABFD9ED547E190A19D7ECF8B9370C864C8EF79761E9EFEDE06BF6776100E696EF17B8A2EC38F77AA86D09D39FD91438AC3FA5D38A4FAA23E1F0EE919D21EE0D984BAE592F6CC0AB106745FAC90DD7DBA77D6F44EBA351F5608F334ED96377F23D33B5C6779F5BF579C9A190E6CB7BCFA9BA30C35939C0C5A5EFDCD51869A793ED86479F53747196AA63ABEC1F2EA6F8E32905889E5ADEC873367D683159677DD085DA6CDBA6497E56D1FA7CBCC597B9B2C6FDF045DE6CFDAD02D4E170B4C1E0E7933A8DF62FED4644E5CD7B760819A8CFFB67685116A329B2774176BEFEA7EE9E2085E1CD17C209822597355F384E08BE4913ECD1F823592F8CA78942992A63DE40BE762ADAC26E4D3338092D4585B130CF9F40CA00C35D63C45219F9E0194A1C65AF9F2904FCF00CA5063AA3137E4D33380329027F921DFAD2B70ACB1F614877CAD77E8628DB5AB32E4EB9DA28B35D6F8FE90EF8F59BA58F39D12A1C61A194CD1851FB8A6DFC2143599C6497D0BA6A8C9AC7AAE5D61873A6D765677011F7DA9BB86E02BF948F3A1C614998711CD1382299263039A3F045324F19571275324ABAAAD809EEED4FDE031A0772B2BA0E77011DC911C5B66051E97427047F2DC422B702F04C11D4938A6B6E658013D93AB4B8DA9C2C55640CFE4CA5063AA60A515D033B93253E55640CFE1E2F8A21BAFB7027A0E17C11449DF197108D648168EA6BA29823592D34FF56910AC91A49E7AAB5D91C11DEB8D79DD055DACB1EE7DA7BBA68B2FECC02165AFAC809EC635496A3239139AE7F090A64D175370EC40B046725B9509EA6D4BDD8C531334266FBD09EABD580453240F2D35C13D25104C916CF59860696DB63B9270AC1963827A4756971A6BB58B4C50EFC8CA50E3A8A3C004F58E9C9A619909EABD581C5374A7F699A0DE8B453045B2F0AC380453240BC6D485608A64EB74EABB52045F24A92FCC695764B0C6EA38BA0BBA5863ED48EAAEE9E20E5370C8B1D79A0F76A8C9CCDCD73C478635ED6CA770EC40B0463273BEA16EC6A9DEA039C180602AFBDC03479C66D0A5C61A271B198F9C72E88E38D9209339E5D00438D9209339E5D0C438D920C369061C537439CD80608A24A719104C91E434038229929C6340F0453263505D38271B1983AAC970B29131A89A0CA71C98A226C329077632E71ECA649F6F643B85630782B5F4B98759603E7BFFE3380B8CC77CFEFEC7ADDDDAADFFDBFA53F8F77F98B35BBBB55B7F0AB5E35EEEE55EEEE55EEEE55EEEE55EEEE55EEEF52F5FFF00BDCB22D8]]>
</MeshData>
</MeshImport>
</Producers>
</Mesh>
<Mesh Name="Mesh_Diamond">
<Producers>
<MeshSphere Scale="0.8 1 0.8" ZSamples="3" RadialSamples="4"/>
</Producers>
</Mesh>
<Mesh Name="Mesh_ToriiCollision">
<Producers>
<MeshBox Comment="left" Scale="0.7 4.3 0.7"/>
<MeshTransform Position="-4.7 -2.1 0"/>
<MeshBox Comment="right" Scale="0.7 4.3 0.7"/>
<MeshTransform Position="4.7 -2.1 0"/>
<MeshCombine/>
<MeshBox Comment="top" Scale="9.5 2 1.2"/>
<MeshTransform Position="0 4.2 0"/>
<MeshCombine/>
</Producers>
</Mesh>
<Mesh Name="Mesh_ColCylinder">
<Producers>
<MeshSphere ZSamples="6" RadialSamples="14"/>
<MeshExpression AutoNormals="0">
<Expression>
<![CDATA[//V : current vertex
//VarP is set to the number of Z samples;
//VarQ is the number of circonferences wanted in the upper and lower faces
float VarP;
int VarQ = 1;
float Psi;
VarP = 6;//OrigSphere.ZSamples;
if (v.Y != 0 || v.X != 0) {
Psi = atan2(v.Y,v.X);
v.X = cos(Psi); //*pow(1-abs(v.Z),2);
v.Y = sin(Psi);
//Normals
//n.X = cos(Psi);
//n.Y = sin(Psi);
if (VarQ == 0) {
v.Z /= 1 - 2/(VarP-1);
}
else { //VarQ != 0
v.Z /= 1 - (VarQ+1)*2/(VarP-1);
if (abs(v.Z)>1.001) { //this is because we are using floating point precision
//it is better to avoid stuff like "Z > 1" due to truncament errors
//remember: tallest's high: (1/(1 - (VarQ+1)*2/(VarP-1));
v.X *= 1 - (abs(v.Z)-1)/(1/(1 - (VarQ+1)*2/(VarP-1))-1);
v.Y *= 1 - (abs(v.Z)-1)/(1/(1 - (VarQ+1)*2/(VarP-1))-1);
v.Z = v.Z/(abs(v.Z));
}
} //ELSE
//Normals
if (abs(v.Z) < 0.999) {
n.Z = 0; //lateral surface
}
else {
if (pow(v.X,2) + pow(v.Y,2) < 0.999) {
n.X = 0; //Upper surface
n.Y = 0;
}
else {
//Edges normals, you can decide what to use.
}
} // End of normals section
//soft edges Work In Progress
/*
if (abs(v.Z) > 0.7 && pow(v.X,2) + pow(v.Y,2) > 0.7) {
v.Z *= 0.9;
v.Y *= 0.9;
v.X *= 0.9;
}
// */
} //OUTER IF]]>
</Expression>
</MeshExpression>
<MeshTransform Rotation="0.25 0 0"/>
</Producers>
</Mesh>
</Children>
</Group>
<Array Name="Axis" Dimensions="1" SizeDim1="2" SizeDim2="3"/>
</Content>
</ZApplication>