Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
ReactPhysics3D — Gideros Forum

ReactPhysics3D

MoKaLuxMoKaLux Member
edited January 2020 in General questions
I am exploring reactphysics3d.
I have a ship (from Paul :) )
local ship = loadObj("3d", "ship.obj")
ship.shape = r3d.BoxShape.new(2, 1, 3)
local v2 = Viewport.new()
v2:setContent(ship)
v2:setPosition(0, 4, 0) -- min 2 for y
v2.body = world:createBody(v2:getMatrix())
v2.body:createFixture(ship.shape, nil, 100)
v2.body:enableGravity(false)
I have the game loop:
stage:addEventListener(Event.ENTER_FRAME, function(e)
	...
	local shipx = v2:getX()
	local shipy = v2:getY()
	local shipz = v2:getZ()
	if isright then shipx += 0.10 end
	if isleft then shipx -= 0.10 end
	if isup then shipy += 0.10 end
	if isdown then shipy -= 0.10 end
--	matrix:setPosition(shipx, shipy, shipz)
--	v2.body:setTransform(matrix)
--	v2:setPosition(shipx, shipy, shipz)
--	ship:setPosition(v2:getPosition())
	ship:setMatrix(v2.body:getTransform())
end)
The ship collides with the boxes but how can I move the ship please?
I am almost there (see the commented lines) but at some point the player crashes.
3d.png 284.1K
my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
Tagged:
«1

Comments

  • I think I found it :)
    	if isright then v2.body:applyForce(32, 0, 0) end
    	if isleft then v2.body:applyForce(-32, 0, 0) end
    	if isup then v2.body:applyForce(0, 32, 0) end
    	if isdown then v2.body:applyForce(0, -32, 0) end
    	ship:setMatrix(v2.body:getTransform())
    That works kind of like liquidfun (box2d).
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • another question please.
    How can I move the ship in the direction it is facing?
    I tried this but getRotationY() is always 0 so that doesn't work.
    	if isup then
    		matrix = v2.body:getTransform()
    --		v2.body:applyForce(0, 0, 16*100)
    		v2.body:applyForce(
    			math.cos(^< matrix:getRotationY()) * 64*10,
    			0,
    			-math.sin(^< matrix:getRotationY()) * 64*10)
    		print(matrix:getRotationX(), matrix:getRotationY(), matrix:getRotationZ())
    	end
    	if isdown then
    --		v2.body:applyForce(0, 0, -16*100)
    		v2.body:applyForce(
    			-math.cos(^< matrix:getRotationY()) * 10*64,
    			0,
    			math.sin(^< matrix:getRotationY()) * 10*64)
    		print(matrix:getRotationX(), matrix:getRotationY(), matrix:getRotationZ())
    	end
    Thank you for your help.
    the project:
    zip
    zip
    3D-Collisions04.zip
    491K
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    Accepted Answer
    Yes, you can’t always reverse a matrix to its Euler angles, so gideros don’t do it at all, although in the case of reactphysics it is always possible... but you can transform your direction vector by the matrix and normalize the result to get a new direction vector.
  • MoKaLuxMoKaLux Member
    edited January 2020
    thank you for your feedback.
    I am "rotating" the ship using torque:
    	if istorqueleft then v2.body:applyTorque(0, -8*64, 0) end
    	if istorqueright then v2.body:applyTorque(0, 8*64, 0) end
    The ship is rotating as expected but I don't know if it changes the rotation of the ship or of the viewport or of the body. All of them don't seem to change, they are always 0. Will do more tests.

    @hgy29 I remember the demo/game you did http://forum.giderosmobile.com/discussion/comment/60150/#Comment_60150. Do you mind sharing the code please?
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    Accepted Answer
    @MoKaLux, I wouldn't mind sharing it, but I'd need to refactor it before, since it uses various bits of code and assets all over my pc.
    And it won't help you since in my demo, the ball was thrown in a known/fixed direction.

    with reactphysics3d, it works pretty much the same as box2d: the collision engine change the transform matrix of the body, then your gideros code copy this matrix to the corresponding sprite. I think your issue is that setting the Matrix of a Sprite doesn't update its rotation/translation nor scale components, it only change its resulting matrix. thus you can't use getRotation() afterwise.

    There are ways to compute back rotation angles from the matrix coeficients, but your problem is easier to solve since you don't need the angles, but the direction vector.

    For example, if your untransformed ship is pointing toward 'z' axis, then you can get the transformed direction vector with the code below:
    		local m=body:getTransform() -- or sprite:getMatrix()
    		local ax,ay,az=m:transformPoint(0,0,0)
    		local bx,by,bz=m:transformPoint(0,0,1)
    		local dx,dy,dz=bx-ax,by-ay,bz-az
    I hope that helps...

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited January 2020
    that is working great <3 , I just need to play with the numbers now. Thank you very much for your answer. I noticed reactphysics3d was working like box2d. I will post the code here when I am done. Peace.

    Likes: keszegh

    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited April 2020
    here is a video and the source file, please feel free to improve.
    youtube.com/watch?v=cE1_uHiOArY
    Code based on gideros 3d collisions demo (hgy29) + ship graphix from Paul.
    main.lua = 146 lines of code :)
    zip
    zip
    3D-Collisions07.zip
    543K
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited January 2020
    Some more questions please. This is how I set up a 3D object.
    -- a ship
    local objship = loadObj("3d/ship", "ship.obj")
    objship.shape2 = r3d.CapsuleShape.new(2, 1)
    local shipvp = Viewport.new()
    shipvp:setContent(objship)
    shipvp:setPosition(0, 10, 0) -- position the ship when starting the game
    shipvp.body = world:createBody(shipvp:getMatrix())
    shipvp.body:createFixture(objship.shape2, nil, 100)
    --shipvp.body:enableGravity(false)
    Now the capsule shape has no friction but we should be able to change the friction value using setMaterial and setFrictionCoefficient(0.5)
    But I don't know how to access the setFrictionCoefficient :/

    From the reactphysics doc it's written:
    Here is how to get the material of a rigid body and how to modify some of its properties:
    // Get the current material of the body
    rp3d::Material& material = rigidBody ->getMaterial();
    // Change the friction coefficient of the body
    material.setFrictionCoefficient(rp3d::decimal(0.2));
    And in the gideros github I see this:
    int r3dBody_SetMaterial(lua_State* L) {
    	Binder binder(L);
    	rp3d::RigidBody* body = static_cast(binder.getInstance(
    			"r3dBody", 1));
    	rp3d::Material& mat = body->getMaterial();
    	lua_getfield(L, 2, "frictionCoefficient");
    	if (!lua_isnil(L,-1))
    		mat.setFrictionCoefficient(luaL_checknumber(L, -1));
    	lua_pop(L, 1);
    }
    https://github.com/gideros/gideros/blob/master/plugins/reactphysics3d/source/Common/reactbinder.cpp
    I tried these but that don't work:
    1- local mat = shipvp.body:getMaterial() mat:setFrictionCoefficient(0.5)
    2- shipvp.body:setMaterial(setFrictionCoefficient(0.5))
    3- shipvp.body:setFrictionCoefficient(0.5)
    Thank you in advance for your help.
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited January 2020
    I found it :)
    local mat = shipvp.body:getMaterial()
    print(mat.frictionCoefficient) -- prints 0.3 
    mat.frictionCoefficient = 0.75
    print(mat.frictionCoefficient) -- prints 0.75
    shipvp.body:setMaterial(mat) -- apply new material
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited January 2020
    another question please. I am creating a sphereshape and I would like to move it towards the front of the ship.
    local objship = loadObj("3d/ship", "ship.obj")
    objship.shape3 = r3d.SphereShape.new(1.5)
    local shipvp = Viewport.new()
    shipvp:setContent(objship)
    shipvp:setPosition(0, 10, 0) -- position the ship when starting the game
    shipvp.body = world:createBody(shipvp:getMatrix())
    shipvp.body:createFixture(objship.shape3, nil, 100) -- shape, transform, mass
    I know it has to do with the transform but what value does it take?
    shipvp.body:createFixture(objship.shape3, nil, 100) -- shape, transform, mass

    What I tried :/ :
    1- objship.shape3:setTransform(0, 5, 10)
    2- objship.shape3:setPosition(0, 5, 10)
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • edit: I think I found it? Is this the way to do it?
    local m = Matrix.new(0, 10, 0)
    shipvp.body:createFixture(objship.shape3, m, 64) -- shape, transform, mass
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    Accepted Answer
    Almost there, just create an empty Matrix and use setPosition on it. Then use the matrix in createFixture

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • that worked, thank you very much hgy29 <3 .
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited January 2020
    some progress here!

    to dos:
    - collision filteringDONE, better vehicle controls, better blender texturing!
    - how to build levels? maybe in tiled?
    - make games/apps :)
    PS: the code is dirty :|
    zip
    zip
    reactphysics3D.zip
    632K
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+4 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited January 2020
    building a 3D map for the levels using TILED (objects) = OK :)
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited January 2020
    I managed to "build" levels using tiled :)
    I tried getting the ship move like a car, no success :#
    I tried getting the ship move like a ship, no success :s
    I tried for days getting the controls right with no success, I would need some help here please!
    I am almost ready to do some tutorials to bring some attention to gideros but I would like to get the controls done before :/
    PS: I removed the factory buildings because it was too large for the zip file.
    zip
    zip
    reactphysics3D.zip
    821K
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    edited January 2020 Accepted Answer
    To move like a ship, I'd do it that way:
    	local gv=0	
    	if isleft then gv=1 end
    	if isright then gv=-1 end
    	if isup then shipbody:applyForce(dx * force, 0, dz * force,ax+dz*gv,ay,az-dx*gv) end
    	if isdown then shipbody:applyForce(-dx * force, 0, -dz * force,ax+dz*gv,ay,az-dx*gv) end
    It will only rotate if you accelerate at the same time. The idea is to apply the force on the right or left side of the ship when you want to turn, and on the center if you don't, as if the propellers power was being adjusted to allow turning your ship.

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited January 2020
    nope that doesn't work, I still get the never ending sliding effects.
    I asked the question on reactphysics3d github:
    https://github.com/DanielChappuis/reactphysics3d/issues/119
    @PaulH could you also please help here :) ?

    I also tried to convert this box2d pdf to reactphysics. My goal would be to kill the lateral velocity.

    In b2d, b2dot =
    inline float32 b2Dot(const b2Vec2& a, const b2Vec2& b)
    {
    return a.x * b.x + a.y * b.y;
    }
    pdf
    pdf
    car_physics.pdf
    150K
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    It was working for me (i tried before replying), but I assumed it was a spaceship, in which case you’d want to keep lateral velocity since there are no frictions in space. Maybe you can query the current velocity, extract the lateral component and apply an opposite force to attenuate it ?

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited January 2020
    thank you very much for your help hgy29, your code is working of course :) what I wanted to say is that the ship keeps sliding even if we have changed direction. I hope to make the ship slide only a little and then go to the correct direction. I tried everything I could. I will try some more the b2d way see what I get (cf:killing lateral velocity). Once again thank you very much for your help <3 .
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    Accepted Answer
    BTW I noticed that current plugin doesn't expose functions to query velocity and set/get damping. I added them for next release and I can send you an updated .dll if you wish.

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited January 2020
    oh yes I would gratefully want it :). I tried to join you on slack but the link above the forum doesn't work anymore.
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    Thanks for flagging, I fixed it. You were already in the slack group though
  • MoKaLuxMoKaLux Member
    edited January 2020
    THAT WORKED :)
    Now simply using this to control the ship (vehicle)
    	if isup then shipbody:applyForce(dx * force, 0, dz * force) end
    	if isdown then shipbody:applyForce(-dx * force, 0, -dz * force) end
    	if isleft then shipbody:applyTorque(0, -torque, 0) end
    	if isright then shipbody:applyTorque(0, torque, 0) end
    and the magic happens here:
    	shipbody:setLinearDamping(0.3)
    Thank you very much hgy29.
    Now some tutorials!

    PS: one little issue with lighting and android. I have this message:
    FragmentShader:
    0:19: L0003: Keyword 'sampler2DShadow' is reserved

    stack traceback:
    3dbase/3DLighting.lua:74: in function 'getShader'
    3dbase/3DLighting.lua:109: in function 'setSpriteMode'
    3dbase/3DShapes.lua:35: in function 'updateMode'
    3d_factory/plane.lua:35: in function 'PLANE_3D'
    main.lua:33: in main chunk

    Likes: hgy29

    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited February 2020
    I am struggling doing some tuts >:) .
    I have started :)
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited February 2020
    I have one more question regarding r3d. I don't know if I should start a new post?
    My question is: can we get the position of a r3d body on only 1 axis?
    I would like to access the position on a certain axis only (for example the body position on the x axis):
    	for k, v in pairs(world.missiles) do
    		v.body:applyForce(0, 0, missilespeed)
    		print(v.body:getTransform()[1])
    --		k:setMatrix(v.body:getTransform()[1])
    --		k:setZ(v.body:getZ())
    	end
    Alternatively, would it be difficult to get the body matrix instead of its transform?
    Transform doesn't take into account the scale, that would be pretty handy.

    Thank you :)

    PS: I see in r3d.cpp file this code:
    static void toTransform(lua_State *L, int n, rp3d::Transform &transform) {
    	Binder binder(L);
    	lua_pushvalue(L, n);
    	if (binder.isInstanceOf("Matrix", -1)) {
    		float mat[16];
    		lua_getfield(L, -1, "getMatrix");
    		lua_pushvalue(L, -2);
    		lua_call(L, 1, 16);
    		for (size_t k = 0; k < 16; k++)
    			mat[k] = luaL_optnumber(L, -16 + k, 0);
    		lua_pop(L, 17);
    		transform.setFromOpenGL(mat);
    	}
    }
    transform.setFromOpenGL(mat) OpenGL doesn't take the scale?
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    Accepted Answer
    1) You can use
    body:getTransform():getX()
    2) You actually get a Matrix from getTransform(), unfortunately reactphysics3d don't handle scaling. https://github.com/DanielChappuis/reactphysics3d/issues/103

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited February 2020
    perfect, thank you very much hgy29 <3
    For the scaling I do it this way when I create the obj:<pre class="CodeBlock">
    	-- the obj
    	self.obj = loadObj(xobjpath, xobjname)
    	local minx, miny, minz = self.obj.min[1], self.obj.min[2], self.obj.min[3]
    	local maxx, maxy, maxz = self.obj.max[1], self.obj.max[2], self.obj.max[3]
    	local width, height, length = maxx - minx, maxy - miny, maxz - minz
    	local matrix = self.obj:getMatrix()
    	matrix:setPosition(params.x,params.y,params.z)
    	matrix:setRotationX(0)
    	matrix:setRotationY(0)
    	matrix:setRotationZ(0)
    	matrix:setScale(3,3,3) -- HERE IT IS
    	self.obj:setMatrix(matrix)
    	-- the obj body
    	self.body = xworld:createBody(self.obj:getMatrix())
    	-- the obj shape
    	self.shape = r3d.SphereShape.new(height / 2 * self.obj:getScaleY()) -- AND I APPLY THE SCALE HERE TOO
    	-- the obj fixture
    	self.body:createFixture(self.shape, nil, 16) -- shape, transform, mass
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited February 2020
    MoKaLux said:

    PS: one little issue with lighting and android. I have this message:
    FragmentShader:
    0:19: L0003: Keyword 'sampler2DShadow' is reserved

    stack traceback:
    3dbase/3DLighting.lua:74: in function 'getShader'
    3dbase/3DLighting.lua:109: in function 'setSpriteMode'
    3dbase/3DShapes.lua:35: in function 'updateMode'
    3d_factory/plane.lua:35: in function 'PLANE_3D'
    main.lua:33: in main chunk

    I found a solution, you can comment these lines (3dbase/3DLighting.lua:74)
    --			v=Shader.new(
    --				ccode..D3._V_Shader,
    --				ccode..D3._F_Shader,
    --				Shader.FLAG_FROM_CODE,
    --				LightingShaderConstants,LightingShaderAttrs)
    --			v:setConstant("lightPos",Shader.CFLOAT4,1,Lighting.light[1],Lighting.light[2],Lighting.light[3],1)
    --			v:setConstant("ambient",Shader.CFLOAT,1,Lighting.light[4])
    --			v:setConstant("cameraPos",Shader.CFLOAT4,1,Lighting.camera[1],Lighting.camera[2],Lighting.camera[3],1)
    --			Lighting._shaders[lcode]=v
    and that works great on android!
    Or you could check if it runs on android first with an if else statement.
    			if application:getDeviceInfo() == "Android" then
    			else
    				v=Shader.new(
    					ccode..D3._V_Shader,
    					ccode..D3._F_Shader,
    					Shader.FLAG_FROM_CODE,
    					LightingShaderConstants,LightingShaderAttrs)
    				v:setConstant("lightPos",Shader.CFLOAT4,1,Lighting.light[1],Lighting.light[2],Lighting.light[3],1)
    				v:setConstant("ambient",Shader.CFLOAT,1,Lighting.light[4])
    				v:setConstant("cameraPos",Shader.CFLOAT4,1,Lighting.camera[1],Lighting.camera[2],Lighting.camera[3],1)
    				Lighting._shaders[lcode]=v
    			end
    I don't know if it can be fixed but we could add the if android statement in github so it works out of the box!?
    Tested on html5 export and that works fine, no lighting errors, so that's only for android (maybe ios too?)
    PEACE.
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    Accepted Answer
    @MoKaLux, it seems like a device specific issue, can you tell me what Gideros writes about OpenGL support when you run your poject ? There are afew 'print' lines at the top of 3DLighting to give opengl version and what extensions are supported
Sign In or Register to comment.