3D Physics with ZgeBullet

Use of external libraries (DLLs) from ZGE.

Moderator: Moderators

User avatar
VilleK
Site Admin
Posts: 2355
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: 3D Physics with ZgeBullet

Post by VilleK »

Thanks to Kjell for fixing the impossible once again and to Ats who doesn't give up when it comes to difficult problems :)
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: 3D Physics with ZgeBullet

Post by Kjell »

Hi Ats,
Ats wrote: Tue Nov 22, 2022 10:01 amWith 250% help from Kjell, the problem I had was corrected.
Hmm .. 250% seems a bit excessive, but i'm glad i could be of help :)

K
User avatar
VilleK
Site Admin
Posts: 2355
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: 3D Physics with ZgeBullet

Post by VilleK »

@Ats: I heard back from Rado1. If you make a pull request of your changes then he can merge it to main repository. I'm not exactly sure how to make a pull request on github but it should be straightforward I hope.
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

Hello, I'm back to ZgeBullet, and I'm currently trying to simply detect what object my sphere is colliding with.
The notice looks pretty straight forward:
@fn int zbtIsCollidedWith(
xptr objA, xptr objB)
@brief Are the specified collision objects collided?
@param objA pointer to collision object A
@param objB pointer to collision object B
@return 0 - objects are not collided; 1 - objects are collided
But I can't get anything with it... I call it in SphereModel / OnUpdate.

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" CameraPosition="0 0 30" MouseVisible="255" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary Comment="Bullet 3D physics" ModuleName="ZgeBullet_x64" CallingConvention="1">
      <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) {}


// 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>
    <ZExpression Comment="Init">
      <Expression>
<![CDATA[// init physical world
xptr World = zbtCreateWorld();
zbtSetCurrentWorld(World);

createModel(ObjectModel);
createModel(SphereModel);]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnUpdate>
    <ZExpression Expression="zbtStepSimulation(App.DeltaTime, 0, 0);"/>
  </OnUpdate>
  <Content>
    <Model Name="ObjectModel" Category="1" RenderOrder="1">
      <Definitions>
        <Variable Name="Body" Type="9"/>
      </Definitions>
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[xptr shape = zbtCreateCylinderShape(1, 10);

Body = zbtCreateRigidBody(1, shape, CurrentModel.Position, CurrentModel.Rotation);

zbtSetDamping(Body, 0.1, 0.1);]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[CurrentModel.Rotation.Z += 0.001;
zbtSetPosRot(Body, CurrentModel.Position, CurrentModel.Rotation);]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <RenderMesh Mesh="CylinderMesh"/>
      </OnRender>
      <OnRemove>
        <ZExpression Comment="Delete rigid body" Expression="zbtDeleteRigidBody(Body);"/>
      </OnRemove>
    </Model>
    <Model Name="SphereModel" Category="1" RenderOrder="1">
      <Definitions>
        <Variable Name="SphereBody" Type="9"/>
      </Definitions>
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[xptr shape = zbtCreateSphereShape(1.0);

SphereBody = zbtCreateRigidBody(1, shape, CurrentModel.Position, CurrentModel.Rotation);

zbtSetCollisionFlags(SphereBody, ZBT_CF_STATIC_OBJECT);]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[float x = App.MousePosition.X*16 * App.ViewportWidth / 800;
float y = App.MousePosition.Y*12 * App.ViewportHeight / 600;

CurrentModel.Position = vector3(x, y, 0);
zbtSetPosRot(SphereBody, CurrentModel.Position, CurrentModel.Rotation);

if (zbtIsColliding(SphereBody)) {
  SphereColor.Color = vector3(0.8, 0.2, 0.2);
 // trace(intToStr(zbtGetNumberOfCollisions(SphereBody)));

} else {
  SphereColor.Color = vector3(0.9, 0.9, 0.9);
}

//zbtStartCollisionDetection();
if (zbtIsCollidedWith(SphereBody, Body))
{
trace("ok");
}]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <RenderSetColor Name="SphereColor" Color="0.9 0.9 0.9 1"/>
        <RenderMesh Mesh="SphereMesh"/>
      </OnRender>
      <OnRemove>
        <ZExpression Comment="Delete rigid body" Expression="zbtDeleteRigidBody(SphereBody);"/>
      </OnRemove>
    </Model>
    <Mesh Name="CylinderMesh">
      <Producers>
        <MeshBox Scale="1 0.5 1" XCount="18" YCount="2" Grid2DOnly="255"/>
        <MeshExpression Scale="1 10 1" AutoNormals="0">
          <Expression>
<![CDATA[float k;
if(abs(v.Y) < 0.5){
  k = v.X * PI;
  v.X = sin(k);
  v.Z = cos(k);
} else {
  v.X = 0;
  v.Z = 0;
}

v.Y = v.Y < 0 ? -1 : 1;

n.X = v.X;
n.Y = v.Y;
n.Z = v.Z;]]>
          </Expression>
        </MeshExpression>
      </Producers>
    </Mesh>
    <Mesh Name="SphereMesh">
      <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>
  </Content>
</ZApplication>


Do I do something wrong, or do you think there is a problem in ZgeBullet source code?

Code: Select all

EXPORT int zbtIsCollidedWith(btCollisionObject* objA, btCollisionObject* objB) {

	for (int i = gCurrentWorld->dispatcher->getNumManifolds() - 1; i >= 0; --i) {
		btPersistentManifold* pm = gCurrentWorld->dispatcher->getManifoldByIndexInternal(i);
		btCollisionObject* coA = const_cast<btCollisionObject*>(pm->getBody0());
		btCollisionObject* coB = const_cast<btCollisionObject*>(pm->getBody1());

		if ((coA == objA && coB == objB) || (coA == objB && coB == objA)) {
			return pm->getNumContacts();

			/* tests shown that this is not necessary
			int j = pm->getNumContacts() - 1;
			for (; j >= 0; --j) 
				if (pm->validContactDistance(pm->getContactPoint(j))) break;
			if (j >= 0) return true;
			return false;*/
		}
	}
	return 0;
}
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: 3D Physics with ZgeBullet

Post by Kjell »

Hi Ats,
Ats wrote: Wed Feb 08, 2023 9:14 pmDo I do something wrong, or do you think there is a problem in ZgeBullet source code?
At the very least, the code that is commented out in zbtIsCollidedWith shouldn't be commented out. As previously established, using validContactDistance might appear superfluous when testing with only axis-aligned bodies ( although even then it's incorrect ), but is in fact necessary for accurate results.

K
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

After a bit of tests, the

Code: Select all

if ((coA == objA && coB == objB) || (coA == objB && coB == objA)) {
never works, and the problem seems to be coming from

Code: Select all

btPersistentManifold* pm = gCurrentWorld->dispatcher->getManifoldByIndexInternal(i);
btCollisionObject* coA = const_cast<btCollisionObject*>(pm->getBody0());
btCollisionObject* coB = const_cast<btCollisionObject*>(pm->getBody1());
I wonder why we retrieve coA and coB like that here :?
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: 3D Physics with ZgeBullet

Post by Kjell »

Hi Ats,

Had a quick look at the Sphere VS Cylinder example you posted ( should have done that sooner ). You're using the Body xptr of ObjectModel in the ZExpression of SphereModel. You can only do that when ObjectModel is spawned as a reference. But since you're spawning it as a clone, that basically results in "zbtIsCollidedWith(SphereBody, null)" .. which will obviously always return false.

That being said, the ZgeBullet problem mentioned in my last post still needs be fixed as well.

K
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

Oh, all right. So with models spawned as reference, the test is running correctly. It's good to know, as it isn't explained in the doc.
But that doesn't help me find when a (clone) laser has touched a (clone) enemy.

Actually, I test if the laser has touched something (enemy, wall...) and then the laser is destroyed.
And if the enemy has touched something (laser, wall...), the enemy loses some life.

I really need to know if the laser has touched an enemy. And right now, the only method that works would be to send a ray and retrieve the model attached to the xptr collision object. (method described here: viewtopic.php?p=10329#p10329)
But that seems really unnecessary...
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: 3D Physics with ZgeBullet

Post by Kjell »

Hi Ats,
Ats wrote: Mon Feb 13, 2023 9:53 amSo with models spawned as reference, the test is running correctly. It's good to know, as it isn't explained in the doc.
Not sure if you're referring to the ZgeBullet docs or the ZGameEditor docs, but this should be common knowledge in ZGE.

Take a look at the example below. It spawns a blue player ( as a clone, but that doesn't matter in this case ) and four orange enemies ( as clones of course, you can't spawn four references of the same model ). Then in the render event of player it shoots a ray at the enemy model .. which doesn't make much sense in this context ( the enemy model isn't even spawned ). But that's basically what you're doing in your example ( with xptr ).

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" CameraPosition="0 0 9" ViewportRatio="3" FOV="90" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="OpenGL32">
      <Source>
<![CDATA[//

void glBegin(int mode){}
void glEnd(){}
void glVertex2f(float x, float y){}]]>
      </Source>
    </ZExternalLibrary>
    <ZExpression>
      <Expression>
<![CDATA[//

createModel(Player);

for(int i=0; i<4; i++)
{
  createModel(Enemy);
}]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <Content>
    <Model Name="Player">
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[//

Player.Position.X = App.MousePosition.X*16;
Player.Position.Y = App.MousePosition.Y*9;]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <RenderSetColor Color="0 0.502 1 1"/>
        <RenderSprite/>
        <ZExpression>
          <Expression>
<![CDATA[//

float x, y;

x = Player.Position.X;
y = Player.Position.Y;

// Shoot ray at enemy ... which doesn't make any sense since all enemies are
// spawned as clones. This way the ray shoots towards the enemy model instead.

glBegin(1);
glVertex2f(0, 0);
glVertex2f(Enemy.Position.X-x, Enemy.Position.Y-y);
glEnd();]]>
          </Expression>
        </ZExpression>
      </OnRender>
    </Model>
    <Model Name="Enemy">
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[//

Enemy.Position.X = random(0, 8);
Enemy.Position.Y = random(0, 4);]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[//

float t = App.Time+Enemy.Personality*PI*2;

Enemy.Velocity.X = sin(t);
Enemy.Velocity.Y = cos(t);]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <RenderSetColor Color="1 0.502 0 1"/>
        <RenderSprite/>
      </OnRender>
    </Model>
  </Content>
</ZApplication>
K
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

Not sure if you're referring to the ZgeBullet docs or the ZGameEditor docs, but this should be common knowledge in ZGE.
I'm referring to the ZgeBullet doc. Since it's an external library, I didn't expect the zbtIsCollidedWith function to only work with reference model.

For the rest, I'm not sure to understand what you are doing. I must have expressed myself badly :oops:

So I made a simple example:
  • You can move around and fire using the mouse
  • Cubes are traversing the screen from left to right
I'm looking to know if a cube has collided with another cube, or with a sphere, in EnemyModel/OnUpdate.

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" CameraPosition="0 0 30" MouseVisible="255" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary Comment="Bullet 3D physics" ModuleName="ZgeBullet_x64" CallingConvention="1">
      <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) {}


// 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 HasInitializer="1">
      <Source>
<![CDATA[int Score = 0;
int Fires = 0;
int Accuracy = 0;]]>
      </Source>
    </ZLibrary>
    <ZExpression Comment="Init">
      <Expression>
<![CDATA[// init physical world
xptr World = zbtCreateWorld();
zbtSetCurrentWorld(World);
zbtSetWorldGravity(0, -10, 0);]]>
      </Expression>
    </ZExpression>
    <SpawnModel Model="GroundModel" SpawnStyle="1"/>
    <SpawnModel Model="PlayerModel" SpawnStyle="1"/>
  </OnLoaded>
  <OnUpdate>
    <ZExpression Expression="zbtStepSimulation(App.DeltaTime, 0, 0);"/>
    <Timer Comment="spawn enemies" Interval="1">
      <OnTimer>
        <SpawnModel Model="EnemyModel"/>
      </OnTimer>
    </Timer>
  </OnUpdate>
  <OnRender>
    <RenderText Comment="Score" X="-0.3" Y="0.8" Scale="0.3">
      <TextExpression>
<![CDATA[//"Hello " + "World " + IntToStr(App.FpsCounter)
"Score: "+intToStr(Score);]]>
      </TextExpression>
    </RenderText>
    <RenderText Comment="Accuracy" X="0.2" Y="0.8" Scale="0.3">
      <TextExpression>
<![CDATA[//"Hello " + "World " + IntToStr(App.FpsCounter)
"Accuracy: "+intToStr(Accuracy)+"%";]]>
      </TextExpression>
    </RenderText>
  </OnRender>
  <Content>
    <Model Name="PlayerModel" Position="-26.42 8 0">
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[float x = App.MousePosition.X*16 * App.ViewportWidth / 800;

CurrentModel.Position = vector3(x, 8, 0);]]>
          </Expression>
        </ZExpression>
        <KeyPress Keys="{" RepeatDelay="1">
          <OnPressed>
            <SpawnModel Model="SphereModel" UseSpawnerPosition="255"/>
          </OnPressed>
        </KeyPress>
      </OnUpdate>
      <OnRender>
        <RenderMesh Mesh="PlayerMesh"/>
      </OnRender>
    </Model>
    <Model Name="EnemyModel" Rotation="0 0 2.029" Category="1" RenderOrder="1">
      <Definitions>
        <Variable Name="EnemyBody" Type="9"/>
      </Definitions>
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[CurrentModel.Position.X = -20;
CurrentModel.Position.Y = random(-2, 5);

CurrentModel.Velocity.X = random(8,4);
CurrentModel.RotationVelocity = rnd();


xptr shape = zbtCreateBoxShape(1, 1, 1);
EnemyBody = zbtCreateRigidBody(1, shape, CurrentModel.Position, CurrentModel.Rotation);]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[
zbtSetPosRot(EnemyBody, CurrentModel.Position, CurrentModel.Rotation);


if (zbtIsColliding(EnemyBody))
{
  // Do this only if enemy colliding with a sphere, but how to test that?
  Score ++;
  Accuracy = 100 * Score / Fires;

  @RemoveModel();
}

if (CurrentModel.Position > 20) @RemoveModel();]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <RenderMesh Mesh="EnemyMesh"/>
      </OnRender>
      <OnRemove>
        <ZExpression Comment="Delete rigid body" Expression="zbtDeleteRigidBody(EnemyBody);"/>
      </OnRemove>
    </Model>
    <Model Name="SphereModel" Position="-27.3 9.12 0" Category="1" RenderOrder="1">
      <Definitions>
        <Variable Name="SphereBody" Type="9"/>
      </Definitions>
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[xptr shape_sphere = zbtCreateSphereShape(1.0);
SphereBody = zbtCreateRigidBody(1, shape_sphere, CurrentModel.Position, CurrentModel.Rotation);

Fires += 1;]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[zbtGetPosRot(SphereBody, CurrentModel.Position, CurrentModel.Rotation);

if (CurrentModel.Position.Y < -10) @RemoveModel();]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <RenderSetColor Name="SphereColor" Color="0.9 0.9 0.9 1"/>
        <RenderMesh Mesh="SphereMesh"/>
      </OnRender>
      <OnRemove>
        <ZExpression Comment="Delete rigid body" Expression="zbtDeleteRigidBody(SphereBody);"/>
      </OnRemove>
    </Model>
    <Model Name="GroundModel" Position="0 -10 0">
      <Definitions>
        <Variable Name="GroundBody" Type="9"/>
      </Definitions>
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[CurrentModel.Position.X = 0;
CurrentModel.Position.Y = -10;
CurrentModel.Position.Z = 0;
CurrentModel.Rotation = 0;

xptr shape = zbtCreateBoxShape(20, 1, 1);
GroundBody = zbtCreateRigidBody(1, shape, CurrentModel.Position, CurrentModel.Rotation);

//zbtSetGravity(GroundBody, 0, 0, 0);]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnUpdate>
        <ZExpression Expression="zbtSetPosRot(GroundBody, CurrentModel.Position, CurrentModel.Rotation);"/>
      </OnUpdate>
      <OnRender>
        <RenderMesh Mesh="GroundMesh"/>
      </OnRender>
      <OnRemove>
        <ZExpression Comment="Delete rigid body" Expression="zbtDeleteRigidBody(GroundBody);"/>
      </OnRemove>
    </Model>
    <Mesh Name="EnemyMesh">
      <Producers>
        <MeshBox XCount="1" YCount="1"/>
      </Producers>
    </Mesh>
    <Mesh Name="SphereMesh">
      <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="PlayerMesh">
      <Producers>
        <MeshSphere ZSamples="3" RadialSamples="3"/>
      </Producers>
    </Mesh>
    <Mesh Name="GroundMesh">
      <Producers>
        <MeshBox Scale="20 1 1"/>
      </Producers>
    </Mesh>
  </Content>
</ZApplication>
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: 3D Physics with ZgeBullet

Post by Kjell »

Hi Ats,
Ats wrote: Mon Feb 13, 2023 4:41 pmSince it's an external library, I didn't expect the zbtIsCollidedWith function to only work with reference model.
No no, it works with clones as well. The mistake you made doesn't have anything to do with external libraries, it's a regular ZGE mistake.

What i tried to explain is that in your ( Feb 8 ) example your "zbtIsCollidedWith(SphereBody, Body)" call is written as-if you're using ObjectModel as a reference. So you should either spawn it as a reference instead of a clone, or you should change your code so it uses your clone ... for instance "zbtIsCollidedWith(SphereBody, MyClone.Body)" after using "MyClone = createModel(ObjectModel)" in your "Init" ZExpression.

K
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

Oh, you are totally right, now I understand my mistake :lol:
But still, I was expecting ZgeBullet to be capable of retrieving what objects are simply colliding, since it can do that with a zbtRayTest followed by zbtGetUserModel.

Right now, since there are a lot of lasers, enemies and other objects, I really don't know how to store "MyClone = createModel(ObjectModel)" and retrieve them when collision occurs.
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: 3D Physics with ZgeBullet

Post by Kjell »

Hi Ats,
Ats wrote: Mon Feb 13, 2023 6:54 pmI was expecting ZgeBullet to be capable of retrieving what objects are simply colliding, since it can do that with a zbtRayTest followed by zbtGetUserModel.
Bullet can tell you which objects / bodies have collided, but that's not very helpful in most circumstances. ZGE doesn't know what Bullet is doing internally, and Bullet doesn't know what ZGE is doing internally. That's exactly why Bullet has the ability to store user data in objects.

So in case you need to know which model a body belongs to on collision, make sure you use zbtSetUserModel so Bullet can tell you.

K
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

So in case you need to know which model a body belongs to on collision, make sure you use zbtSetUserModel so Bullet can tell you.
But that is my whole problem:

Only zbtRayTest returns a collision object, that can be reverted to a Model, using zbtGetUserModel (and obviously zbtSetUserModel when I attached the collision object to the Model, when spawned).

I don't find any other way to retrieve the collided object, as every other ZgeBullet functions returns an int or a void.

I think I'm going to check how zbtRayTest is programmed, and add my own function in ZgeBullet in order to retrieve the first collision object that is listed in the collisions manifold of the object. Some kind of fusion between:

Code: Select all

EXPORT int zbtGetNumberOfCollisions(btCollisionObject* obj) {

	int numCol = 0;

	btDispatcher *dispatcher = gCurrentWorld->world->getDispatcher();
	int numManifolds = dispatcher->getNumManifolds();

	for (int i=0; i<numManifolds; i++) {
		btPersistentManifold *contactManifold = dispatcher->getManifoldByIndexInternal(i);

		const btCollisionObject *obA = contactManifold->getBody0();
		const btCollisionObject *obB = contactManifold->getBody1();

		if (obA != obj && obB != obj) continue;

		int numContacts = contactManifold->getNumContacts();

		for (int j=0; j<numContacts; j++) {
			btManifoldPoint &pt = contactManifold->getContactPoint(j);
			if (pt.getDistance() < 0.f) numCol++;
		}
	}

	return numCol;
}
and

Code: Select all

EXPORT btCollisionObject* zbtRayTestFiltered(float fromX, float fromY, float fromZ, float toX, float toY, float toZ,
	int filterGroup, int filterMask) {

	btCollisionWorld::ClosestRayResultCallback crrc(btVector3(fromX, fromY, fromZ), btVector3(toX, toY, toZ));
	crrc.m_collisionFilterGroup = filterGroup;
	crrc.m_collisionFilterMask = filterMask;
	gCurrentWorld->world->rayTest(btVector3(fromX, fromY, fromZ), btVector3(toX, toY, toZ), crrc);
	if (crrc.hasHit()) {
		gCurrentWorld->rayTestHitPoint = crrc.m_hitPointWorld;
		gCurrentWorld->rayTestHitNormal = crrc.m_hitNormalWorld;

		return const_cast<btCollisionObject*>(crrc.m_collisionObject);
	}
	else
		return NULL;
}
Or maybe not the first object in the list, but the object with the most collision points in the manifolds, in case the tested object is overlapping several other objects. That should work.


Edit:

I'm going to try with:

Code: Select all

EXPORT btCollisionObject* zbtGetMainCollidedObject(btCollisionObject* obj) {
	btDispatcher* dispatcher = gCurrentWorld->world->getDispatcher();
	int numManifolds = dispatcher->getNumManifolds();
	btCollisionObject* collidedObject = nullptr;
	int maxNumContacts = -1;
	
	for (int i = 0; i < numManifolds; i++) {
		btPersistentManifold* contactManifold = dispatcher->getManifoldByIndexInternal(i);

		const btCollisionObject* obA = contactManifold->getBody0();
		const btCollisionObject* obB = contactManifold->getBody1();

		if (obA != obj && obB != obj) continue;

		int numContacts = contactManifold->getNumContacts();

		if (numContacts > maxNumContacts) 	{
			maxNumContacts = numContacts;
			if (obA != obj) collidedObject = const_cast<btCollisionObject*>(obA);
			if (obB != obj) collidedObject = const_cast<btCollisionObject*>(obB);
		}
	}
	return collidedObject;
}

Edit 2:

Cool, it worked perfectly :shock:

In my example above, I'm testing the collision in EnemyModel/OnUpdate like that:

Code: Select all

if (zbtIsColliding(EnemyBody)) {
  xptr pointer = zbtGetMainCollidedObject(EnemyBody);
  if (pointer != null) {
    model m = zbtGetUserModel(pointer);
    if (if (m.Category == 2) {
      Score ++;
      Accuracy = 100 * Score / Fires;
    }
  }
  @RemoveModel();
}
Should I make a pull request with that new function on ZgeBullet github?
Last edited by Ats on Mon Oct 07, 2024 8:27 am, edited 1 time in total.
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: 3D Physics with ZgeBullet

Post by Kjell »

Hi Ats,
Ats wrote: Tue Feb 14, 2023 9:30 amI don't find any other way to retrieve the collided object, as every other ZgeBullet functions returns an int or a void.
For those kind of situations i think zbtGetNumOverlappingObjects and zbtGetOverlappingObject ( which returns a btCollisionObject ) are intended.

But that's the beauty of open-source, you can modify everything to your own liking :wink:

K
Post Reply