Jump to content
  • Advertisement
Sign in to follow this  
ClaF

Slicing a body

This topic is 2697 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I'm using Farseer physics engine and would like to be able to slice a body into two pieces. What would be the best way of doing this in Silverlight? It's similar to the 'Cut the rope' game where you slice the rope and it cuts at that place. Any suggestions on what technique I should use? Thanks for any help

Share this post


Link to post
Share on other sites
Advertisement
i think you want to make two dffrent models from one model splitted by a plane







so there: from nvidia portal engine






procedure AddVertex(const x: t3dpoint; var res: TPolygon);
begin

// Append a vertex to a polygon.
if (res.Count = 0) or
(magnitude(vectors_substract_v1minusv2(x, res.V[res.Count-1])) > 0.01) then
begin
INC(res.Count);
res.V[res.Count-1] := x;
end;

end;

function ClipEdge(const v1, v2: t3dpoint; const plane: t3dpoint): t3dpoint;
var
v: t3dpoint;
t: Single;
begin

// Clip a line segment to a plane, return the new end point.
v := vectors_substract_v1minusv2(v2, v1);
// t := -sdotPlaneVecDist(plane, v1) / iloczynskalarny3d(plane, v);
Result := vectors_add(v1, vector_multiple(v, t));

end;

function dotVecScalarMult3(v: TDotVector3; s: Single): TDotVector3;
begin

Result.x := v.x * s;
Result.y := v.y * s;
Result.z := v.z * s;

end;


function ClipPoly(const poly: TPolygon; const plane: t3dpoint): TPolygon;
var
a, b: t3dpoint;
count, i: Integer;
da, db: Integer;
clipped: TPolygon;
begin

// Clip a polygon to a plane.
count := poly.Count;
clipped.Count := 0;

for i := 0 to count - 1 do
begin
a := poly.V;
b := poly.V[(i+1) mod count];

da := classifyapointagainstaplane(a,plane,getplaned(plane,a));
db := classifyapointagainstaplane(b,plane,getplaned(plane,b));

if da < 1 then
begin
AddVertex(a, clipped);
if db = 1 then AddVertex(ClipEdge(a, b, plane), clipped);
end
else if db = -1 then
begin
AddVertex(ClipEdge(a, b, plane), clipped);
AddVertex(b, clipped);
end;
end;

Result := clipped;
result.normal := poly.normal;
end;

[/quote]







but in other words












const float SPECIAL_FEAUTRE = 0.00000001; //wtf ;u called epsilon

const int isOnPlane = 0;
const int isFront = 1;
const int isBack = -1;


int __fastcall classifyapointagainstaplane(t3dpoint point,t3dpoint normal,float distance)
{
float costam;
int result;
costam = dotproduct(point,normal)+distance;
if (costam > 0) result = isFront;
if (costam < 0) result = isBack;
if (betweenorequal(-SPECIAL_FEAUTRE,SPECIAL_FEAUTRE,costam) == true) result = isOnPlane;

return result;
}









[/quote]







so we have model- models have vertices the vertices represent polygons the polygons have sides




heres a function that i made years ago :P actually i didnt finish this function at all






void __fastcall TachoGLModel::SplitByPlane(int delete_side, t3dpoint split_normal, float split_distance,t3dpoint point_on_split_plane)
{
int i;
bool found=false;
int BASE_SIDE;
int j;
t3dpoint vline[2];

t3dpoint C[2];
int SPLIT_COUNT=0;
int cnt=0;
LIGHT_TRAIL NEW_FACE;


for (i = 0; i < VBO_BE.Length; i++) {
found = false;

for (j = VBO_BE.INDEX_START+1; j < VBO_BE.INDEX_START+VBO_BE.length; j++) {
BASE_SIDE = classifyapointagainstaplane(VBO_V[j-1],split_normal,split_distance);
if (classifyapointagainstaplane(VBO_V[j],split_normal,split_distance) != delete_side ) cnt = cnt + 1;

if (classifyapointagainstaplane(VBO_V[j],split_normal,split_distance) != BASE_SIDE) {
vline[0] = VBO_V[j-1];
vline[1] = VBO_V[j];
C[SPLIT_COUNT] = PUNKT_PRZECIECIA_ODCINEK_PLASZCZYZNA(split_normal,point_on_split_plane,vline);
SPLIT_COUNT = SPLIT_COUNT + 1;

}
}//eof for j


SPLIT_COUNT = 0;
NEW_FACE.set_length(cnt+2);
cnt = -1;

for (j = VBO_BE.INDEX_START+1; j < VBO_BE.INDEX_START+VBO_BE.length; j++) {
BASE_SIDE = classifyapointagainstaplane(VBO_V[j-1],split_normal,split_distance);
if (classifyapointagainstaplane(VBO_V[j],split_normal,split_distance) != delete_side ) { cnt = cnt + 1; NEW_FACE[cnt] = VBO_V[j]; }

if (classifyapointagainstaplane(VBO_V[j],split_normal,split_distance) != BASE_SIDE) {

cnt = cnt + 1; NEW_FACE[cnt] = C[SPLIT_COUNT];

SPLIT_COUNT = SPLIT_COUNT + 1;

}
}//eof for j

Replace_Face(NEW_FACE,i);
//REPLACE FACE

//nie dokonczone

}



}



[/quote]







and again in other words:




go through all faces (polygons ) in a mesh:

test where they are ( front or back of split plane)




if tehe is at least one vertex that is different from BASE_SIDE (note that base side is a side for first vertex in face)

we must split this face

now compare

two sides from wrong vertex:




ONE_SIDE = vectorAB( VERTS[ WRONG_INDEX], VERTS[WRONG_INDEX + 1]);

SECOND_SIDE = vectorAB( VERTS[ WRONG_INDEX], VERTS[WRONG_INDEX - 1]);




if WRONG_INDEX is 0 then wrong_index - 1 equals to tle last face vert

if wrong_index is the last face vert then wrong__index +1 is the first face index = 0




then you calculate point of intersection between line and plane:




there are many wasy to do iit and i dont have the simpliest code for doing that but i dont care














t3dpoint __fastcall PUNKT_PRZECIECIA_ODCINEK_PLASZCZYZNA(t3dpoint vNormal,t3dpoint pointonplane,
t3dpoint vLine[2])
{
const Extended MATCH_FACTOR = 0.9999999999;


t3dpoint vIntersection;// : t3dpoint;
Extended originDistance;
Extended distance1;
Extended distance2;
double m_magnitude;// : Double;
t3dpoint vPoint;// : t3dpoint;
t3dpoint vLineDir;// : t3dpoint;
Extended Numerator;// : Extended;
Extended Denominator;// : Extended;
Extended dist;// : Extended;
Extended Angle,tempangle;// : Extended;
t3dpoint vA, vB;// : t3dpoint;
int I;
Extended dotProduct;// : Extended;
Extended vectorsMagnitude;// : Extended;

t3dpoint result;

originDistance = 0;
distance1 = 0;
distance2 = 0;
vPoint.x = 0;
vPoint.y = 0;
vPoint.z = 0;

vLineDir.x = 0;
vLineDir.y = 0;
vLineDir.z = 0;

Numerator = 0.0;
Denominator = 0.0;
dist = 0.0;
Angle = 0.0;



originDistance = -1 * ((vNormal.x * pointonplane.x) +
(vNormal.y * pointonplane.y) +
(vNormal.z * pointonplane.z));


distance1 = ((vNormal.x * vLine[0].x) +
(vNormal.y * vLine[0].y) +
(vNormal.z * vLine[0].z)) + originDistance;

distance2 = ((vNormal.x * vLine[1].x) +
(vNormal.y * vLine[1].y) +
(vNormal.z * vLine[1].z)) + originDistance;

if(distance1 * distance2 >= 0) {
t3dpoint r; //linia nie przebija plaszczyzny
r.x = 1.0f; r.y = 1.0f; r.z = 1.0f;
return r;
}




vLineDir.x = vLine[1].x - vLine[0].x;
vLineDir.y = vLine[1].y - vLine[0].y;
vLineDir.z = vLine[1].z - vLine[0].z;

m_magnitude = sqrt((vLineDir.x * vLineDir.x) +
(vLineDir.y * vLineDir.y) +
(vLineDir.z * vLineDir.z) );

if (m_magnitude == 0.0) m_magnitude = 1.0f;


vLineDir.x = vLineDir.x/m_magnitude;
vLineDir.y = vLineDir.y/m_magnitude;
vLineDir.z = vLineDir.z/m_magnitude;



Numerator = -1 * (vNormal.x * vLine[0].x +
vNormal.y * vLine[0].y +
vNormal.z * vLine[0].z + originDistance);




Denominator = ( (vNormal.x * vLineDir.x) + (vNormal.y * vLineDir.y) + (vNormal.z * vLineDir.z) );

if( Denominator == 0.0) {

vIntersection = vLine[0];
return vIntersection;
} else {



dist = Numerator / Denominator;



vPoint.x = (vLine[0].x + (vLineDir.x * dist));
vPoint.y = (vLine[0].y + (vLineDir.y * dist));
vPoint.z = (vLine[0].z + (vLineDir.z * dist));

result.x = vPoint.x; // Return the intersection point
result.y = vPoint.y;
result.z = vPoint.z;

}

return result;

}

[/quote]











after calc this point you should create a new face .....




hope ihelped lol

Share this post


Link to post
Share on other sites
Thanks. I understand some of it, and have managed to get intersection points. The hard part is using this in Silverlight as I can't seem to render the fixture to a UIElement. Btw, this is 2D.

Share this post


Link to post
Share on other sites
for me its harder to explain this in 2d because of equation y=ax+b when whe have prependicular line to OX line ( there is one X and infinite Y :P)




for those equation lets try and use vertex.z = 0 then ;) for any normal or vertex or plane equation

Share this post


Link to post
Share on other sites
I've managed to get Farseer to take care of most of the intersection points and such. But the resulting vertices of each new body has to someone be displayed as an UIElement. This is what's now tripping me up sad.gif

Share this post


Link to post
Share on other sites
sorry cant help you at this stage i dont know ms silversight (but i have installed it lol) and farser




try this http://www.google.pl/search?hl=pl&client=opera&hs=4NP&rls=en&channel=suggest&q=drawin+on+UIElement&aq=f&aqi=&aql=&oq=




:P

Share this post


Link to post
Share on other sites
lol don't think I haven't tried! biggrin.gif Trying to find how to create a UIElement for a given fixture and attach it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!