Jump to content
  • Advertisement
Sign in to follow this  

Slicing a body

This topic is 2779 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
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);

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


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

// 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));


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

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


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

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

for i := 0 to count - 1 do
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
AddVertex(a, clipped);
if db = 1 then AddVertex(ClipEdge(a, b, plane), clipped);
else if db = -1 then
AddVertex(ClipEdge(a, b, plane), clipped);
AddVertex(b, clipped);

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


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;


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 j;
t3dpoint vline[2];

t3dpoint C[2];
int cnt=0;

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);

}//eof for j

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];


}//eof for j


//nie dokonczone




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:



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;



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=


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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!