Superb FREE Box2d Physics Effects Inc Water/Liquid/Buoyancy...BUT...

insertcode

I said it before and I said it again (you posted your code on “share your code”)

This is perhaps one of the coolest things to come around in some time.
It’s a very cool addition. I am looking forward to this thing getting polished :slight_smile:

*watches intensely*

ng [import]uid: 61600 topic_id: 16060 reply_id: 60471[/import]

Hello guys,

I’m currently working on porting the Box2D buoyancy controller from AS3 to LUA … I’m almost there …I think :).
I just need to debug the function that calculates the submerged area of a body. I think it’s a index problem (in AS3 arrays start at 0)…I’ve modified the indexes but I can figure it out.

Anyway here’s the code in LUA:

[lua]function ComputeSubmergedArea(params)

local normal = params.normal;
local offset = params.offset;
local the_body=params.body;
–vertices arrray
– get it from the body or pass it in
local m_vertices=params.vertices;
– basically we’re using just rectangles so we’ve got 4 vertexes
– use count from above
local m_vertexCount= 4 --params.vcount;
local xf={};
xf.position={the_body.x, the_body.y};
local RR={};
RR.col1={1,0};
RR.col2={0,1};
xf.R=RR;

function SetAngle(par)

local c = math.cos(par.angle);
local s= math.sin(par.angle);
local R=par.R;
R.col1[1] = c; R.col2[1] = -s;
R.col1[2] = s; R.col2[2] = c;

return R;
end

function Dot(para)

local a=para.first;
local b=para.second;
local d=a[1] * b[1] + a[2] * b[2];

return d;
end

function MulTMV(para)

local u={Dot({first=para.v, second=para.A.col1}), Dot({first=para.v, second=para.A.col2})}

return u;
end

xf.R=SetAngle({R=xf.R,angle=the_body.rotation});

– Transform plane into shape co-ordinates

local normalL= MulTMV({A=xf.R, v=normal});
local offsetL= offset - Dot({first=normal, second=xf.position});

local depths={};
local diveCount = 0;
local intoIndex = -1;
local outoIndex = -1;

local lastSubmerged = false;
local isSubmerged;
local i;

for i = 1, m_vertexCount, 1 do
— DOT && MIN_VALUE
depths[i] = Dot({first=normalL, second=m_vertices[i]}) - offsetL;

isSubmerged = depths[i] < -0.0000000000001;
if (i > 1) then

if (isSubmerged) then

if not(lastSubmerged) then

intoIndex = i - 1;
diveCount=diveCount+1;
end

else

if (lastSubmerged) then
outoIndex = i - 1;
diveCount=diveCount+1;
end
end

end
lastSubmerged = isSubmerged;

end

if (diveCount==0) then

if (lastSubmerged ) then
print(‘Completly submerged’)
-------------------------------------------------------totaly submerged
return 100;

else
–Completely dry
print(‘Completly dry’)
return 0;
end

elseif (diveCount==1) then
if (intoIndex == -1) then

intoIndex = m_vertexCount - 1;

else

outoIndex = m_vertexCount - 1;
end

end

local intoIndex2 = (intoIndex ) % m_vertexCount;
local outoIndex2 = (outoIndex ) % m_vertexCount;
print(intoIndex, intoIndex2, outoIndex, outoIndex2);
local intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]);
local outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]);

local intoVec = {m_vertices[intoIndex][1] * (1 - intoLamdda) + m_vertices[intoIndex2][1] * intoLamdda,
m_vertices[intoIndex][2] * (1 - intoLamdda) + m_vertices[intoIndex2][2] * intoLamdda};
local outoVec = {m_vertices[outoIndex][1] * (1 - outoLamdda) + m_vertices[outoIndex2][1] * outoLamdda,
m_vertices[outoIndex][2] * (1 - outoLamdda) + m_vertices[outoIndex2][2] * outoLamdda};

– Initialize accumulator

area = 0;
center = {0,0};
p2= m_vertices[intoIndex2];
p3={}

– An awkward loop from intoIndex2+1 to outIndex2
i = intoIndex2;
while (i ~= outoIndex2) do

i = (i ) % m_vertexCount;
if(i == outoIndex2) then
p3 = outoVec;
else
print("nr i ",i)
p3 = m_vertices[i];
end
local triangleArea = 0.5 * ( (p2[1] - intoVec[1]) * (p3[2] - intoVec[2]) - (p2[2] - intoVec[2]) * (p3[1] - intoVec[1]) );
area = area + triangleArea;
– Area weighted centroid
center[1] = center[1] + triangleArea * (intoVec[1] + p2[1] + p3[1]) / 3;
center[2] = center[2] + triangleArea * (intoVec[2] + p2[2] + p3[2]) / 3;

p2 = p3;

end

–Normalize and transform centroid
function Multiply§
local v= {}

v[1]=p.vector[1] * p.factor;
v[2]=p.vector[2] * p.factor;

return v;

end

–center=Multiply({factor=1 / area, vector=center});
–c.SetV(b2Math.MulX(xf, center));

–print ("Submerged Area: ", area );

return area;

end[/lua]

and here is the AS3 function:
[as3]
public override function ComputeSubmergedArea(
normal:b2Vec2,
offset:Number,
xf:b2Transform,
c:b2Vec2):Number
{
// Transform plane into shape co-ordinates
var normalL:b2Vec2 = b2Math.MulTMV(xf.R, normal);
var offsetL:Number = offset - b2Math.Dot(normal, xf.position);

var depths:Vector. = new Vector.();
var diveCount:int = 0;
var intoIndex:int = -1;
var outoIndex:int = -1;

var lastSubmerged:Boolean = false;
var i:int;
for (i = 0; i < m_vertexCount;++i)
{
depths[i] = b2Math.Dot(normalL, m_vertices[i]) - offsetL;
var isSubmerged:Boolean = depths[i] < -Number.MIN_VALUE;
if (i > 0)
{
if (isSubmerged)
{
if (!lastSubmerged)
{
intoIndex = i - 1;
diveCount++;
}
}
else
{
if (lastSubmerged)
{
outoIndex = i - 1;
diveCount++;
}
}
}
lastSubmerged = isSubmerged;
}
switch(diveCount)
{
case 0:
if (lastSubmerged )
{
// Completely submerged
var md:b2MassData = new b2MassData();
ComputeMass(md, 1);
c.SetV(b2Math.MulX(xf, md.center));
return md.mass;
}
else
{
//Completely dry
return 0;
}
break;
case 1:
if (intoIndex == -1)
{
intoIndex = m_vertexCount - 1;
}
else
{
outoIndex = m_vertexCount - 1;
}
break;
}
var intoIndex2:int = (intoIndex + 1) % m_vertexCount;
var outoIndex2:int = (outoIndex + 1) % m_vertexCount;
var intoLamdda:Number = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]);
var outoLamdda:Number = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]);

var intoVec:b2Vec2 = new b2Vec2(m_vertices[intoIndex].x * (1 - intoLamdda) + m_vertices[intoIndex2].x * intoLamdda,
m_vertices[intoIndex].y * (1 - intoLamdda) + m_vertices[intoIndex2].y * intoLamdda);
var outoVec:b2Vec2 = new b2Vec2(m_vertices[outoIndex].x * (1 - outoLamdda) + m_vertices[outoIndex2].x * outoLamdda,
m_vertices[outoIndex].y * (1 - outoLamdda) + m_vertices[outoIndex2].y * outoLamdda);

// Initialize accumulator
var area:Number = 0;
var center:b2Vec2 = new b2Vec2();
var p2:b2Vec2 = m_vertices[intoIndex2];
var p3:b2Vec2;

// An awkward loop from intoIndex2+1 to outIndex2
i = intoIndex2;
while (i != outoIndex2)
{
i = (i + 1) % m_vertexCount;
if(i == outoIndex2)
p3 = outoVec
else
p3 = m_vertices[i];

var triangleArea:Number = 0.5 * ( (p2.x - intoVec.x) * (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x) );
area += triangleArea;
// Area weighted centroid
center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3;
center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3;

p2 = p3;
}

//Normalize and transform centroid
center.Multiply(1 / area);
c.SetV(b2Math.MulX(xf, center));

return area;
}
[/as3]

If anyone can help with getting this working I would really appreciate it. I’m planing on sharing the hole thing with the community as soon as I finish porting it (I still need to port some code for circular shapes and bodies with multiple shapes).

Thanks.

[import]uid: 88546 topic_id: 16060 reply_id: 78167[/import]