static void DestroyThisBodyCallback (const NewtonBody* body, const NewtonJoint* contactJoint) { NewtonWorld* world; NewtonMesh* topMesh; NewtonMesh* bottomMesh; NewtonMesh* effectMesh; RenderPrimitive* srcPrimitive; dMatrix matrix; dFloat maxForce; dVector point; dVector dir0; dVector dir1; // Get the world; world = NewtonBodyGetWorld (body); // find a the strongest force maxForce = 0.0f; for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { dVector force; NewtonMaterial* material; material = NewtonContactGetMaterial (contact); NewtonMaterialGetContactForce (material, &force.m_x); if (force.m_x > maxForce) { dVector normal; NewtonMaterialGetContactPositionAndNormal(material, &point[0], &normal[0]); NewtonMaterialGetContactTangentDirections (material, &dir0[0], &dir0[0]); } } // get the visual primitive srcPrimitive = (RenderPrimitive*) NewtonBodyGetUserData (body); // get the effect mesh that is use to create the debris pieces effectMesh = srcPrimitive->m_specialEffect; // calculate the cut plane plane NewtonBodyGetMatrix (body, &matrix[0][0]); dMatrix clipMatrix (dgGrammSchmidt(dir0) * dYawMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)) * dRollMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f))); clipMatrix.m_posit = point; clipMatrix.m_posit.m_w = 1.0f; clipMatrix = clipMatrix * matrix.Inverse(); // break the mesh into two pieces NewtonMeshClip (effectMesh, meshClipper, &clipMatrix[0][0], &topMesh, &bottomMesh); if (topMesh && bottomMesh) { dFloat volume; NewtonMesh* meshPartA = NULL; NewtonMesh* meshPartB = NULL; volume = NewtonConvexCollisionCalculateVolume (NewtonBodyGetCollision(body)); // the clipper was able to make a cut now we can create new debris piece for replacement dMatrix clipMatrix1 (dgGrammSchmidt(dir1) * dYawMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)) * dRollMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f))); NewtonMeshClip (bottomMesh, meshClipper, &clipMatrix1[0][0], &meshPartA, &meshPartB); if (meshPartA && meshPartB) { // creat another split (you can make as many depend of the FPS) CreateDebriPiece (body, meshPartA, volume); CreateDebriPiece (body, meshPartB, volume); NewtonMeshDestroy(meshPartA); NewtonMeshDestroy(meshPartB); } else { CreateDebriPiece (body, bottomMesh, volume); } NewtonMeshDestroy(bottomMesh); dMatrix clipMatrix2 (dgGrammSchmidt(dir1) * dYawMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)) * dRollMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f))); NewtonMeshClip (topMesh, meshClipper, &clipMatrix2[0][0], &meshPartA, &meshPartB); if (meshPartA && meshPartB) { // creat another split (you can make as many depend of the FPS) CreateDebriPiece (body, meshPartA, volume); CreateDebriPiece (body, meshPartB, volume); NewtonMeshDestroy(meshPartA); NewtonMeshDestroy(meshPartB); } else { CreateDebriPiece (body, topMesh, volume); } NewtonMeshDestroy(topMesh); // remove the old visual from graphics world SceneManager* system = (SceneManager*) NewtonWorldGetUserData(world); delete srcPrimitive; system->Remove(srcPrimitive); // finally destroy this body; NewtonDestroyBody(world, body); } }
void wxSVGCanvasCairo::DrawCanvasImage(wxSVGCanvasImage& canvasImage, cairo_surface_t* cairoSurface, wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem) { if (cairoSurface == NULL) return; cairo_save(m_cr); // ClipPath if (style.GetClipPath().GetCSSPrimitiveType() == wxCSS_URI && style.GetClipPath().GetStringValue().length() > 1) { wxString clipPathId = style.GetClipPath().GetStringValue().substr(1); wxSVGClipPathElement* clipPathElem = (wxSVGClipPathElement*) svgElem.GetElementById(clipPathId); if (clipPathElem && clipPathElem->GetDtd() == wxSVG_CLIPPATH_ELEMENT) { clipPathElem->SetOwnerSVGElement(&svgElem); clipPathElem->SetViewportElement(&svgElem); wxSVGMatrix clipMatrix(matrix); clipPathElem->UpdateMatrix(clipMatrix); SetClipPath(clipPathElem, clipMatrix); } } SetMatrix(m_cr, matrix); // scale context double x = canvasImage.m_x; double y = canvasImage.m_y; double scaleX = canvasImage.m_width / canvasImage.m_image.GetWidth(); double scaleY = canvasImage.m_height / canvasImage.m_image.GetHeight(); wxSVG_PRESERVEASPECTRATIO align = canvasImage.GetPreserveAspectRatio().GetAlign(); bool alignX = false; if (align > wxSVG_PRESERVEASPECTRATIO_NONE) { scaleY = canvasImage.m_height / canvasImage.GetDefaultHeight(); if (canvasImage.GetPreserveAspectRatio().GetMeetOrSlice() != wxSVG_MEETORSLICE_SLICE) { alignX = scaleX > scaleY; } else { cairo_rectangle(m_cr, x, y, canvasImage.m_width, canvasImage.m_height); cairo_clip(m_cr); alignX = scaleX < scaleY; } if (alignX) { scaleX = scaleY; if (align == wxSVG_PRESERVEASPECTRATIO_XMIDYMIN || align == wxSVG_PRESERVEASPECTRATIO_XMIDYMID || align == wxSVG_PRESERVEASPECTRATIO_XMIDYMAX) x += (canvasImage.m_width - canvasImage.GetDefaultWidth() * scaleX) / 2; else if (align == wxSVG_PRESERVEASPECTRATIO_XMAXYMIN || align == wxSVG_PRESERVEASPECTRATIO_XMAXYMID || align == wxSVG_PRESERVEASPECTRATIO_XMAXYMAX) x += canvasImage.m_width - canvasImage.GetDefaultWidth() * scaleX; } else { scaleY = scaleX; if (align == wxSVG_PRESERVEASPECTRATIO_XMINYMID || align == wxSVG_PRESERVEASPECTRATIO_XMIDYMID || align == wxSVG_PRESERVEASPECTRATIO_XMAXYMID) y += (canvasImage.m_height - canvasImage.GetDefaultHeight() * scaleY) / 2; else if (align == wxSVG_PRESERVEASPECTRATIO_XMINYMAX || align == wxSVG_PRESERVEASPECTRATIO_XMIDYMAX || align == wxSVG_PRESERVEASPECTRATIO_XMAXYMAX) y += canvasImage.m_height - canvasImage.GetDefaultHeight() * scaleY; } scaleY = scaleY * canvasImage.GetDefaultHeight() / canvasImage.m_image.GetHeight(); } cairo_translate(m_cr, x, y); cairo_scale(m_cr, scaleX, scaleY); // prepare to draw the image cairo_set_source_surface(m_cr, cairoSurface, 0, 0); // use the original size here since the context is scaled already... cairo_rectangle(m_cr, 0, 0, canvasImage.m_image.GetWidth(), canvasImage.m_image.GetHeight()); // paint if (style.GetMask().GetCSSPrimitiveType() == wxCSS_URI && style.GetMask().GetStringValue().length() > 1) { wxString maskId = style.GetMask().GetStringValue().substr(1); wxSVGMaskElement* maskElem = (wxSVGMaskElement*) svgElem.GetElementById(maskId); if (maskElem && maskElem->GetDtd() == wxSVG_MASK_ELEMENT) { maskElem->SetOwnerSVGElement(&svgElem); maskElem->SetViewportElement(&svgElem); cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, svgElem.GetWidth().GetAnimVal()/scaleX, svgElem.GetHeight().GetAnimVal()/scaleY); cairo_t* cr = cairo_create(surface); wxSVGMatrix maskMatrix; maskMatrix = maskMatrix.Translate(x, y).ScaleNonUniform(scaleX, scaleY).Inverse(); DrawMask(cr, maskElem, maskMatrix, style, svgElem); cairo_mask_surface(m_cr, surface, 0, 0); cairo_destroy(cr); cairo_surface_destroy(surface); } } else { cairo_paint_with_alpha(m_cr, style.GetOpacity()); } cairo_new_path(m_cr); // clean up cairo_restore(m_cr); }