3D Physics with ZgeBullet

Use of external libraries (DLLs) from ZGE.

Moderator: Moderators

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

Re: 3D Physics with ZgeBullet

Post by Ats »

Now I manage to compile the file using:

gcc -shared -c -I ~/bullet3-3.09/src/ -o ZgeBullet.so ZgeBullet.cpp

But it also compiles with -fPIC instead of -shared, the size of the final library is different though. I don't really know which one to chose, even after reading the explanation: https://stackoverflow.com/questions/486 ... -vs-shared

Anyway, I compiled one of Rado1 example by setting ./ZgeBullet.so to the ZExternalLibrary Modulename, but when I launch the elf, it only displays "./ZgeBullet.so" in the terminal. So I don't think this is working.


Edit:
To produce only the compiled code (without any linking), use the -C option.
Ok, -c option wasn't what I needed to do, as the resulted so file is in fact, the o file...
Option -save-temps just confirmed that.


Edit 2:
I can get an so file by doing that:
gcc -Wall -fPIC -I ~/bullet3-3.09/src -c *.cpp
gcc -shared -Wl,-soname,ZgeBullet.so -o ZgeBullet.so *.o

(still trying to figure out what's going on with soname: https://stackoverflow.com/questions/126 ... raries-for)


Edit 3: 8)
gcc -fPIC -I ~/bullet3-3.09/src -c ZgeBullet.cpp
gcc -shared -o ZgeBullet.so ZgeBullet.o
Last edited by Ats on Mon Apr 19, 2021 8:43 pm, edited 8 times in total.
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

Oh, maybe it isn't a problem with the compiled library, as I just tried to load my SunVox example, which was working before when compiled on i386, but now it only displays "./sunvox_lofi.so"... Did you change something about the way library path is handled during the SDL2 update?

I also tried to build ZDesigner.exe again, but now I'm getting errors:
[dcc32 Error] ZExpressions.pas(2060): E2003 Undeclared identifier: 'WinApi'
[dcc32 Error] ZExpressions.pas(2060): E2066 Missing operator or semicolon
[dcc32 Fatal Error] BitmapProducers.pas(35): F2063 Could not compile used unit 'ZExpressions.pas'
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 »

I made a update so ZDesigner should build again.

If it displays the .so filename on start then that means the module could not be loaded

ZExpressions line 2037:
ZHalt(Self.ModuleName);

This has not changed with the SDL-update (ZGE still use the dlopen function).

Are you sure the sunvox.so file is a 64-bit build? I think you can check with "objdump" but I don't know the command line syntax.
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

As ZgeBullet is my last problem before being able to run Omeganaut on linux (maybe), I'm back at experimenting. And after a lot of tries, I finally managed to get something: I had to link the compiled "so" files from bullet3, not the "o" files.

gcc -Wall -fPIC -I ~/bullet3-3.09/src -c ZgeBullet.cpp
gcc -shared -o ZgeBullet.so ~/bullet3-3.09/build_cmake/src/BulletCollision/libBulletCollision.so ~/bullet3-3.09/build_cmake/src/BulletDynamics/libBulletDynamics.so

bullet_demo4.png
bullet_demo4.png (257.55 KiB) Viewed 30466 times

The weird thing is that instead of several cubes dropping from the ceiling and going through the two white blocks, there's one cube circling around like a moon on the X/Z plane... I'm not sure if this is coming from ZgeBullet. I'm going to compile all ZGE examples for linux x86_64 and check if everything is correct.


Edit:
Just to be sure, I managed to compile bullet3-2.83.7 using the build sh script that is present in the version 2.89. No errors, but the cube is still satellited.

Edit 2:
Never mind, I didn't add ZgeBullet.o to ZgeBullet.so linking... So there was no way for it to work in ZGE. The cube is at its original position, before being handled by ZgeBullet. And the cube isn't circling around, it's due to the camera movement... :oops:
When I add ZgeBullet.o to the linking, the library isn't recognized by ZGE. Same as before.
User avatar
zakkwylde
Posts: 29
Joined: Sun Feb 24, 2008 1:38 am
Location: France

Re: 3D Physics with ZgeBullet

Post by zakkwylde »

[quote=Rado1 post_id=7909 time=1449271119 user_id=102]
As part of preparing a "technology" for my new physic-based 3d space flying game I updated also ZgeBulet to version 2.3. The main motivation was to improve and fix rotations and to use Bullet's internal quaternion coputations instead of having this math in ZGE expressions. Thanks to this, ZgeBullet provides quite comfortable means to simply implement movement of an object (airplane or spaceship) in 3D space.

See [url=https://github.com/Rado-1/ZgeBullet/wik ... 2015-12-05]the version history[/url] for details. Download ZgeBullet v2.3 from [url=https://github.com/Rado-1/ZgeBullet/releases/tag/v2.3]here[/url]. All "official" ZgeBullet demos and FL physic-based effects work. It has already been pushed to ZGE git repo, so next beta release of ZGE should have it included as a built-in external library.
[/quote]

Hi Rado,

I am in the midst of building a flight sim as well. Have been trying to make sense of quarternions and how we can code this in ZGE but no, i am still stumped. If ZGEBullet can do it, I am happy to let it. Now for the tutorial - how do we do it? Am new to using libraries, have been making FPSes so far without them, just to clarify my noob status. Would appreciate your help!
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: 3D Physics with ZgeBullet

Post by Kjell »

Hi zakkwylde,
zakkwylde wrote: Thu Dec 30, 2021 7:29 amHave been trying to make sense of quarternions and how we can code this in ZGE but no, i am still stumped.
Quaternions are pretty unintuitive yes. However, once you get familiar with them they're not that difficult to use & don't require a ton of code either. Below is a very basic example ( use arrow keys + A/D to yaw ).

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="Quaternion" CameraPosition="0 0 0" FOV="60" RenderOrder="1" FileVersion="2">
  <OnLoaded>
    <ZLibrary Comment="Quaternion">
      <Source>
<![CDATA[//

vec4 quaternionMultiply(vec4 a, vec4 b)
{
  vec4 q;

  q.x = a.x*b.w+a.w*b.x+a.y*b.z-a.z*b.y;
  q.y = a.y*b.w+a.w*b.y+a.z*b.x-a.x*b.z;
  q.z = a.z*b.w+a.w*b.z+a.x*b.y-a.y*b.x;
  q.w = a.w*b.w-a.x*b.x-a.y*b.y-a.z*b.z;

  return q;
}

//

vec4 axisAngleToQuaternion(vec3 axis, float angle)
{
  float h, s, x, y, z, w;

  h = angle*0.5;
  s = sin(h);

  x = axis.x*s;
  y = axis.y*s;
  z = axis.z*s;
  w = cos(h);

  return vector4(x, y, z, w);
}

//

mat4 rotationMatrix(vec4 q)
{
  mat4 m;

  float x2, y2, z2, xx, xy, xz, yy, yz, zz, wx, wy, wz;

  x2 = q.x*2;
  y2 = q.y*2;
  z2 = q.z*2;

  xx = q.x*x2; xy = q.x*y2; xz = q.x*z2;
  yy = q.y*y2; yz = q.y*z2; zz = q.z*z2;
  wx = q.w*x2; wy = q.w*y2; wz = q.w*z2;

  m[0,0] = 1-(yy+zz);
  m[0,1] = xy+wz;
  m[0,2] = xz-wy;
  m[0,3] = 0;

  m[1,0] = xy-wz;
  m[1,1] = 1-(xx+zz);
  m[1,2] = yz+wx;
  m[1,3] = 0;

  m[2,0] = xz+wy;
  m[2,1] = yz-wx;
  m[2,2] = 1-(xx+yy);
  m[2,3] = 0;

  m[3,0] = 0;
  m[3,1] = 0;
  m[3,2] = 0;
  m[3,3] = 1;

  return m;
}]]>
      </Source>
    </ZLibrary>
    <ZExpression>
      <Expression>
<![CDATA[//

CameraQuaternion = vector4(0, 0, 0, 1);]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnUpdate>
    <Repeat Name="AxisRepeat" Count="3" WhileExp="//">
      <OnIteration>
        <ZExpression>
          <Expression>
<![CDATA[//

int i = AxisRepeat.Iteration;

//

Axis[i] = 0;

//

AxisPositive.CharCode = AxisMap[i,0];
AxisNegative.CharCode = AxisMap[i,1];]]>
          </Expression>
        </ZExpression>
        <KeyPress Name="AxisPositive" CharCode="68">
          <OnPressed>
            <ZExpression>
              <Expression>
<![CDATA[//

Axis[AxisRepeat.Iteration]++;]]>
              </Expression>
            </ZExpression>
          </OnPressed>
        </KeyPress>
        <KeyPress Name="AxisNegative" CharCode="65">
          <OnPressed>
            <ZExpression>
              <Expression>
<![CDATA[//

Axis[AxisRepeat.Iteration]--;]]>
              </Expression>
            </ZExpression>
          </OnPressed>
        </KeyPress>
      </OnIteration>
    </Repeat>
    <ZExpression>
      <Expression>
<![CDATA[//

float dt, rx, ry, rz;

dt = App.DeltaTime;

rx = Axis[2]*2*dt;
ry = Axis[1]*2*dt;
rz = Axis[0]*2*dt;

//

vec4 qx, qy, qz, q;

qx = axisAngleToQuaternion(vector3(0, 1, 0), rx);
qy = axisAngleToQuaternion(vector3(1, 0, 0), ry);
qz = axisAngleToQuaternion(vector3(0, 0, 1), rz);

q = quaternionMultiply(qz, qy);
q = quaternionMultiply(qx, q);

CameraQuaternion = quaternionMultiply(q, CameraQuaternion);]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <OnRender>
    <ZExpression>
      <Expression>
<![CDATA[//

mat4 m;

getMatrix(0, m);
setMatrix(0, m * rotationMatrix(CameraQuaternion));]]>
      </Expression>
    </ZExpression>
    <UseMaterial Material="TowerMaterial"/>
    <RenderMesh Mesh="TowerMesh"/>
  </OnRender>
  <Content>
    <Array Name="Axis" SizeDim1="3"/>
    <Array Name="AxisMap" Type="4" Dimensions="1" SizeDim1="3" SizeDim2="2" Persistent="255">
      <Values>
<![CDATA[78DA535755D37071040003820120]]>
      </Values>
    </Array>
    <Variable Name="CameraQuaternion" Type="8"/>
    <Mesh Name="TowerMesh">
      <Producers>
        <MeshImport HasVertexColors="1">
          <MeshData>
<![CDATA[78DAED985F68D45716C76F7E93D49AA86DE322047C1404591F76B72C298A0F7DD9971542C087CD124D0275184B273A355BDC9FB003BFEC0886914CD8C858AAA9422C04EC834F0B2D851463405CD02E8140DA74A130E082B2E94EAC8D33FEF67EE733D7DF643369E26E17F661907B723CF7DCF3E77BCE3DBFDC8CC58CF97B93311FFFEACFD3FE9F3A3ED7CFBFFCBAF3CDCF87126FEAE740614FE74061A0F0D56703857D65A824A2739E24973BC48B7EF5D99C27FDCB1DD2871795CEE58E3D9DFBCA973BBEFA6C5F79CE133FE789977CA020B9687D1DF10305F1A2115F7B56F2394FF2394F1251BCBB38455D3CF0FBCA92EF2B4B228A77C52F3BA2E265CDE5482EE448EE78711E9DC49D7576B44B840E3D798C6210C2E25D244E224D63C4431DF250C5600CB1C9B231CACE51172708383C8D518E50972F92084FED3A9C25E71416D07172A70F95172898B87CA3D8C0DFF1CA54961D0ECE8B1053FC2029CB512E2E5F973BBB7877B570F8D7C6E36CD6FA7248D6222CB98B4DBB375BB67F79E8C1F42E5163BAE7B2DFA4768B1E7AB0FDCBC32BB797C2F0F692F8430FB2DF74CF85E1E115C9D90D4349A49FDA2D6A8CECDC6C79634718BEB1035EF6A1D3BBE0E5C518D1D46EE9209FDEC5297438CB2E9A78A9AF3FBD0B3931D45AC05794C5E115E257E4D96F9411991E7A20F9A10768C2232747F4391BED8203C8600DCDD46E5163A439BD4BF4668B34A77789DE6C91A631A2A9DDF2F8C68E48E7660B12F4230BB5B11183D344A7D6BE1038BC4265A929F54522DC6E2F092B6AC7EEE195A807C8C218ACE18B98D1C102A76A7DD54AB08F3524EC7296DCC1AA36FEDA53C446FC204C15A80868D3155499EAD32D58266672C1A377D44B0F5D2A1EF1D2F15CF1482615CF7947037FE8523E9949B54D9D3F1EF8E5ABE78F7BE9F2D57CD24BB74DFD2697493D3C62B5D2C5234397BCB47774E852E07B47CB5703FFFCF1B6A94C2A9F4C5E0CFCADFDF1512FFDB4273E1AF84F7BDAA6BC743E59BEEAA5ADC51356BFCF8FDBB3BD7EDCF2BDC109CBF795CE047EF148E98C2C8B1EE891E4404FF95AE027F38F266C9CE38F266C6CE3C98B5E7A6B7FF364E0E7079B27ADE5C1C757BC742EF1F84AE0E712B7AC3C96B965E5B18CFC8A4A52BEE6A593F9A73D811F1FDDDA6FF98B5BFBADE58B67C76D8E13C3799BE3B5E1BCE5AF9D1DB7FC442E11F88FAFE407BD74F3647E30F09B2773092FFDF88AA2BA35A908A16D5392B44DB566F774FA7DADD96CC2EF1B9EC82696534F7B2CAAA3363F3F17F7FA6C8427BC3ECB9FF07A2D1F5F4EEDE91C9E584E6513C3137E5F36D19AF5FBF674B6668727F6742EA7C00D0C830B5E7ABFA581BFBFE7808D7FEC0296C9E580E5C72E100955231EEAF55A26F0DBA7867292BF96F1D2ED53AA5DDB1498A85EF11C5593A474468841F3493CC632AA452CA35A08D5D219218C0E08C773548AAABD730A2A89A22D9D5177898A2717C96319222723F19204FE3BA7C4434B6784EAF084507558811B280967101315E68A2D38A5388353F4067D420515DBAD49C5766B92CABAD894AFFA5F9498858CF85846BBD078EEBC4558FDA95E1526C523DC08FA569817ABB743B8A173A08A21B8390C15A18B5608480255F7CAAF6AF7C5A4AAF6C5E4D805453E7641915353AA492EAE1BC5932337978EA593B9C5F498FA6D39255E54180A55D7BD74B2D0F6FB845E7CD4C5A638856A7C9448864685E1D0A8B025426E283A9C05556E01F71D0CB905200F6ECC046E31379A89C16C89A25D4E111B3301EFDC59EE3251D5D62EEAAE58864CE95B7AD861AE8AD4F63F95A28B8884A8A25D3A6DEC02916093DC9936EC72E39830C4498420467D6BEF26726E01FDC95D002B2609BCE680EDE30A92D1AD59DDB1DC32260633C14D2D7961FE330FAB3A957B41E7D0337414727A9BB9C41CE646F32D703DAF6E474E6599096EAA4B727E50166AEBCE570079756656BE4474325F01A616539A5BC0AC6376B99B2B1DEE26F7942F14BDE77A493DCF1DA7A39824CC49A60DB3119EB9CAFC41073EB2D09A45871BC44C6022D1FF7881A7FFE96128124E6181998C05379FE5AB76E2111B13B21A7F2553EAC25718ACE83D2277F35FD640955EA57BCF0FEABB4315A808DF6BBE5CF49BBE3BF9412ACE37942EA25EF4125DCA5780EA6313FB58701DAB998FE5E59431FA1A1AA3EC8CD197D498E594784D7E5124A29A638E6A26489F53B51234B1E05EB5DD73EE6D3B5010EF5E79DD73EEB528DEBD70A5EF5E7FE279F7E965D43D17BD58EBF17A31C9BE7BED3ABEF66C3D1DF77EC497F3581B1B5145EF5C5E91B2C98B52BBBCACF50E52FCBC4C65CDE5428EE44E8EEEF50A2FFBABDFD792BB37AFC30ABFEE2F06C4E0FE6EE078E21928B4BF3F53EC1B3F989B293ECA1E1C992996C69A3F9C29DE7977F8E24C71E80FEDD744BBC7678A1FBF07BFD7F27BCF49A763041D782C600D9DD6DFCF14DBAEB69E9D297E347EE3B42CC7AC4EF903E87C20F9DFFE281DFCC2A3CF59740A49E9DFEB95AF4F4ECC143F7DEFEB638A10F9F5A4FCDE7F4B7EF1022FCDBDE7A4D931820E3CF2630959C3A6EC14FAE5F7F584FCCEF7B28B179D7D7852368304DEE1E5ABF03667D141220482048881243695CBEB09E538DF8B2F78E55E785B9814FAD181472E541F9EC466F3875D8B1D237BC7BB16F79E3B98EB5AB4F5AAEC4AAE7A752DAA5EA2DD5647F5128F3E67AB3AEF772DF65984BB16DBAEDE38DDB5581A2B24BB16CB1F203F3822492C27095EE0E783AE45D54BA7D08147DE7AB6422B36BF3E265F9F9C90DF63097964172FD793B279FF2DF9C23B3CFA9C45E75EAFCEEA94AAD3B5A8EA742DCEF72297BE3A41B9E3055E6755AFAE45D54B3AF0C8E55155934DE5259C2551A66E172FCA4B35128F7778F4398B8E700BECEEC2AC761766B56B693F726A418DF0D2FEFEC2ACE40BB3922FCC4ABE30FBF024A7B08004CDFB6F895E4F4A72E3B476E7838559A1218FF0786F3D2BBE90941D3491A0895CD684F6C2ACD05E98ED1811156EB28F2FED7EFADEBDDE8559E12C1E9D63094938850524682A06F5C3C2ACFA4154361F65E55775178F77C5561A5354EA40F1E8700A79FB35D9DC3B2E2F42A96344F8A80FA5832F61551A134A9A60B28F044D4E214727B276E75DF01FBE282F503C1AD3643C23DA649A4DCCFE33F6FF61D86C69CB2A1EBD98A5CD9BE2D7B7B9B1AFD53A1BDB8919FD85A2C94A57C7502B7FD178D6B3B9197E3367D78F796D24D13FA25D0957C226D3665A9FEBA2B71A93FA76D6EAAC57B5F5E4F5FE4531C4D658FE3EFC3EF4AAD1AE8E273A550F818D2359AF7FC016EB4DCF918EFA3CB213494AA1B45F36CFECCF7245BFD96CA96AD6EF967F5ACD6FC3D7ACBCBD4EC73EB1BB8FC3ED7677479D5AAC6773C99EFA47B8D3CA7F5247E749F8C4D67DBBD9F683F7427CD3F3ECBCEA7E2D86CAF45925C7D82A4CCA6139D429DDF672050FED2E57B3A8F5B86C778BE12B56FEEA9A381FDB28F5B3CD4AB6FD87F7EE876B47FCCF429763ACA21B56337AC9CA4AA1A958F3369827F061A88A730F3D5BF5F52BF5623C75DF28DA7FEFEACDF7C07A7D0562DF87DF594BAE5BA2AEA8C5B91CC69E47FAC31DA51CB4D3F23C23E28F553BC77B5EA3581545AF72F357C2AD56BEA5D20F9165FD0D3856ED474EBD5C1383A9D857F55E5A1395B72A47A7FF346CAA76B9A9545DF2EFAA5DB8DA63A9A2B9C5DA7F75D554DCB89ADFDA1C97C276CBEFACD3459A71DF85DB8C105FBFB7A369A6BFE833ED4AD5EFC0DAE9B45E3F288792C5D5B333B59EAFBF3E9B7F266C7FDAE4D99B3A67F96D66BFE5F79B5828795841AAB972479ED9F573F3CB0A7FB7826F6785BF635787F96DA8B31F59FE77E67E45FE33BB7EB149C4FEBBDF1936F37BC28BFE5EB1F66BB8B1E652F8ADC57BA79DF2F5F49FD85B16DBE03EBEC89CC7A6EEF98FF7EDF8DFC5F9FF6F73B333F3C78EB37E3762F315FBFF7673F7EEDDB0B11AABB11AABB11AABB11AABB11AABB11AABB11A6BB3EB5F359D640C]]>
          </MeshData>
        </MeshImport>
      </Producers>
    </Mesh>
    <Material Name="TowerMaterial" Shading="1" DrawBackFace="255"/>
  </Content>
</ZApplication>
K
User avatar
zakkwylde
Posts: 29
Joined: Sun Feb 24, 2008 1:38 am
Location: France

Re: 3D Physics with ZgeBullet

Post by zakkwylde »

Kjell, Rado,

Thank you very much for the help.
I will work on it and show you where i am at.

Cheers!


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

Re: 3D Physics with ZgeBullet

Post by Ats »

Hello, I have a little question regarding the zbtRayTest which returns a xptr:
xptr zbtRayTest(float fromX, float fromY, float fromZ, float toX, float toY, float toZ)
Perform ray casting between two points in world and return the first hit collision object, or null if no object appears between the two points.
@param fromX, fromY, fromZ position of the raycasting source point
@param toX, toY, toZ position of the raycasting target point
@return pointer to the first hit collision object, or null if no object was hit
Is there a way to retrieve the coordinates of the collision point from that xptr?

Edit:

All right, I got it. At first, I thought that it could be retrieved as easily as XYZ in a Vector3, but there is a function for that:
void zbtGetRayTestHitPointXYZ(ref float outX, ref float outY, ref float outZ)
Get position of previous ray test hit.
@details To obtain correct value, call zbtRayTest() function before.
@param[out] outX, outY, outZ output vector of hit position in the world space
So my next question is... How does it work? Since that function returns a void...

Edit 2:

Don't mind me, it was pretty easy to use. Unusual, but easy :wink:

Code: Select all

xptr point = zbtRayTest(PlayerShip.Position.X, PlayerShip.Position.Y, PlayerShip.Position.Z,
                            PlayerShip.Position.X - 20, PlayerShip.Position.Y, PlayerShip.Position.Z);
vec3 pos;
zbtGetRayTestHitPointXYZ(pos.X, pos.Y, pos.Z);
trace(intToStr(pos.X));
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 at messing with ZGEBullet. I'm trying to get the velocity of an object touched by zbtRayTest, but I can only easily retrieve it's position and rotation. So I'm trying to retrieve the model instead, without success.

Code: Select all

xptr point = zbtRayTest(Player.Position.X, Player.Position.Y, Player.Position.Z,
                            Player.Position.X + 20, Player.Position.Y, Player.Position.Z);

if (point != null)
{
      vec3 pos, rot;
      zbtGetPosRotXYZ(point, pos.X,pos.Y,pos.Z, rot.X,rot.Y,rot.Z);
      trace(intToStr(pos.X));

      model m = zbtGetUserModel(point); <- THIS IS RETURNING NULL!??
      trace(intToStr(m.Position.X)); // <- SO THIS IS CRASHING
}

I don't know what I am missing, since zbtGetUserModel works like this:
model zbtGetUserModel(xptr obj)
@brief Get user-defined ZGE model instance from collision object.
@param obj pointer to collision object
@return object's user-defined ZGE model instance

Edit:
All right, I think I found what I was missing. Writing down the problem always helps to clear the mind...
I had to use this to attach the model to the collision object when creating the model:

Code: Select all

void zbtSetUserModel(xptr obj, model userModel) {}
User avatar
zakkwylde
Posts: 29
Joined: Sun Feb 24, 2008 1:38 am
Location: France

Re: 3D Physics with ZgeBullet

Post by zakkwylde »

Kjell,

I have a couple queries with the code provided previously.
1) In the keypress assignments, only 2 keys were shown. But the commands to rotate along the axes are the 4 cursor arrows. Could you point me to where the commands are programmed?

2) What would the code be for moving or increasing velocity in the vector of the camera? Tried using the FPS engine WSAD commands to configure movement but they were not feasible.

3) Speaking of the FPS Engine, which you kindly provided some time back. The projectiles dispensed upon mouseclick worked down if you kept the aimpoint low to the horizon but when you pointed up vertically, they were off the aimpoint and went in some slant direction. Is there any way to harness ZgeBullet commands? if so, how do we start?

Thanks a million guys!
Zakkwylde




[quote=zakkwylde post_id=10218 time=1643086377 user_id=56]
Kjell, Rado,

Thank you very much for the help.
I will work on it and show you where i am at.

Cheers!


zakkwylde
[/quote]
User avatar
Kjell
Posts: 1915
Joined: Sat Feb 23, 2008 11:15 pm

Re: 3D Physics with ZgeBullet

Post by Kjell »

Hi zakkwylde,
zakkwylde wrote: Sat Aug 13, 2022 12:49 pmIn the keypress assignments, only 2 keys were shown. But the commands to rotate along the axes are the 4 cursor arrows. Could you point me to where the commands are programmed?
The ZExpression in the AxisRepeat component sets the CharCode property of the AxisPositive and AxisNegative components for 3 different axes ( hence the repeat count of 3 ). So even though there are only two KeyPress components, they are used 3 times each .. resulting in a total of 6 keys being used.
zakkwylde wrote: Sat Aug 13, 2022 12:49 pmWhat would the code be for moving or increasing velocity in the vector of the camera?
I've attached a example that shows how to move a ship that uses a quaternion for rotation in it's forward direction. The controls are the same as before ( arrow keys to pitch & roll + A/D to yaw ) but i've added shooting using the spacebar and the ability to adjust the camera a little using the mouse. Hopefully this example helps you understand how to do these types of things.
zakkwylde wrote: Sat Aug 13, 2022 12:49 pmTried using the FPS engine WSAD commands to configure movement but they were not feasible.
Not exactly sure what FPS example you're referring to.
zakkwylde wrote: Sat Aug 13, 2022 12:49 pmSpeaking of the FPS Engine, which you kindly provided some time back. The projectiles dispensed upon mouseclick worked down if you kept the aimpoint low to the horizon but when you pointed up vertically, they were off the aimpoint and went in some slant direction.
Even though it should be pretty trivial to add vertical aiming ( i assume the FPS example only allowed horizontal aiming ), this won't help you in context of a flight simulator where Euler Angles won't suffice.
zakkwylde wrote: Sat Aug 13, 2022 12:49 pmIs there any way to harness ZgeBullet commands? if so, how do we start?
No idea, that's a question for Rado1 :wink:

K
Attachments
FX-01.zgeproj
(111.81 KiB) Downloaded 559 times
User avatar
zakkwylde
Posts: 29
Joined: Sun Feb 24, 2008 1:38 am
Location: France

Re: 3D Physics with ZgeBullet

Post by zakkwylde »

Kjell,

Thanks for the prompt reply! Will work on the sample you gave!


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

Re: 3D Physics with ZgeBullet

Post by Ats »

Hello everyone. I'm back to ZGE after two full month of working on something else, and I just discovered one weird thing with ZgeBullet and/or my game.
I had the feeling that something was off in Omeganaut and here it is: the test zbtIsColliding is behaving strangely...

When the shape of the cylinder is "simple", the collision seems to be a box that encompasses the cylinder.
So when it is vertical or horizontal (fig. A), like a lot of the objects in my game, everything's fine.
But if it's rotated (fig. B), it's a mess... It just works like the ZGE basic Box3D collision shape.

Code: Select all

shape = zbtCreateCylinderShape(0.5, 10);
collision01.png
collision01.png (51.06 KiB) Viewed 28044 times
.

On the contrary, if the shape is "complex", the collision works better:

Code: Select all

shape = zbtCreateCompoundShape();
zbtAddChildShape(shape, zbtCreateCylinderShape(0.5, 10), 0,0,0, 0,0,0);
And yet, it's not perfect... It gets the collision correctly, but then it stays collided as long as the ball stays in the rectangle :roll:

...

I could replace all shapes by compound shapes in my game, but it would be overkill for what it is supposed to do. And as it is all but too weird, I made a simple example to show this problem and iterate on it. Maybe I'm doing something very wrong from the start...? :|

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="if(ANDROID) this.ModuleName = &quot;./libZgeBullet.so&quot;;">
      <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-2015 Radovan Cervenka

  Version: 2.1 (2015-06-27)
*/


// 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 zbtApplyTorqueImpulse(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 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 zbtSetCharacterUpAxis(xptr controller, int axis) {}

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 gravity) {}

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 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 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 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) {}

int zbtStartCollisionDetection() {}

int zbtGetNextContact(xptr outObjA, xptr outObjB,
	xptr outPosA, xptr outPosB, xptr outNormal) {}

void zbtGetCollidedObjects(int contactIndex, xptr outObjA, xptr outObjB) {}

int zbtIsColliding(xptr obj) {}

int zbtGetNumberOfCollisions(xptr obj) {}

int zbtIsCollidedWith(xptr objA, xptr objB) {}


// Raycasting

xptr zbtRayTest(float fromX, float fromY, float fromZ, float toX, float toY, float toZ) {}

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[shapeType = -1;

// init physical world
xptr World = zbtCreateWorld();
zbtSetCurrentWorld(World);]]>
      </Expression>
    </ZExpression>
    <CallComponent Component="InitScene"/>
  </OnLoaded>
  <OnUpdate>
    <ZExpression Expression="zbtStepSimulation(App.DeltaTime, 0, 0);"/>
    <KeyPress Comment="click" Keys="{" RepeatDelay="1">
      <OnPressed>
        <ZExpression Name="InitScene">
          <Expression>
<![CDATA[shapeType *= -1;

@RemoveAllModels();

createModel(ObjectModel);
createModel(SphereModel);]]>
          </Expression>
        </ZExpression>
      </OnPressed>
    </KeyPress>
  </OnUpdate>
  <OnRender>
    <RenderTransformGroup Name="transformSquare" Scale="2.505 19.8425 1">
      <Children>
        <UseMaterial Material="MaterialWireframe"/>
        <RenderSprite/>
      </Children>
    </RenderTransformGroup>
  </OnRender>
  <Content>
    <Model Name="ObjectModel" Category="1" RenderOrder="1">
      <Definitions>
        <Variable Name="Body" Type="9"/>
      </Definitions>
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[xptr shape;

if (shapeType > 0) {
  shape = zbtCreateCylinderShape(0.5, 10);
  trace("Simple shape");
} else {
  shape = zbtCreateCompoundShape();
  zbtAddChildShape(shape, zbtCreateCylinderShape(0.5, 10), 0,0,0, 0,0,0);
  trace("Compound shape");
}

Body = zbtCreateRigidBody(1, shape, CurrentModel.Position, CurrentModel.Rotation);]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[CurrentModel.Rotation.Z += 0.001;
zbtSetPosRot(Body, CurrentModel.Position, CurrentModel.Rotation);

float a = CurrentModel.Rotation.Z * PI*2 - PI/2;
transformSquare.Scale.X = abs(cos(a)) * 20;
transformSquare.Scale.Y = abs(sin(a)) * 20;]]>
          </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);]]>
          </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);
}]]>
          </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>
    <Variable Name="shapeType" Type="1"/>
    <Material Name="MaterialWireframe" Shading="2"/>
  </Content>
</ZApplication>
Edit:
I added mouse click to easily switch from Simple Shape to Coumpound Shape.
I added the collision area to really see what's going on.
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

Since I need to advance in order to release a version of Omeganaut, I transformed the simple cylinder shape of the pillars to a compound shape, just like in the example above. Right now, they are the only models that are rotated like that.

So laser with simple sphere collision shape are working nicely and are now able to pass under the pillars.
But the player ship, with its compound shape made out of 3 scalable spheres for the hull and the wings, doesn't... I'm still searching why.

I can't believe I stumble on huge problems like that just by rotating a pillar after years of using ZgeBullet for collisions... :(
User avatar
Ats
Posts: 762
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: 3D Physics with ZgeBullet

Post by Ats »

With 250% help from Kjell, the problem I had was corrected. It was coming from the ITERATE_MANIFOLDS_FOR_OBJECT macro in the c++ wrapper of the Bullet3 library. And since there is still no news from Rado1, and I hope that he is fine, I forked his project on GitHub.

It includes:
  • Correction for collision between rotated objects
  • Missing macro and relative paths in the Visual Studio project to build ZgeBullet.dll for Windows
  • Linux script to build ZgeBullet.so for Linux
  • Linux script to build libZgeBullet.so for Android
Post Reply