I have a list of ID2D1Geometry objects and I'm trying to use CompareWithGeometry to detect collisions in Direct2D; unfortunately, I'm not getting the results I need. I suspect I am improperly using the inputGeometryTransform parameter.
If I pass in D2D1::Matrix3x2F::Identity() or nullptr for this parameter, I almost always get D2D1_GEOMETRY_RELATION_CONTAINS (3) or D2D1_GEOMETRY_RELATION_IS_CONTAINED (2) results back for the returned D2D1_GEOMETRY_RELATION. On the other hand, if I try and pass in the product of the scale and translation matrices that I used to generate the primary geometry, then I never get collisions.
Can someone help me understand what I need to pass in for the inputGeometryTransform parameter?
The source code that I believe to be relevant appears below:
// This is Shawn Eary's broken code and it is licensed 2012 under the
// Microsoft Public License (Ms-PL) which is compatible with the
// Open Source Initiative
//
// Shawn Eary is not affiliated with Microsoft.
// He just likes the Ms-PL
void SpaceObject::updateDynamics(
Microsoft::WRL::ComPtr<ID2D1DeviceContext> const i_d2dContext,
D2D1::Matrix3x2F const & tranformMatrix)
{
D2D1_SIZE_F renderTargetSize = i_d2dContext->GetSize();
float const worldWidth = renderTargetSize.width / 2.0f;
float const halfWorldWidth = worldWidth / 2.0f;
float const worldHeight = renderTargetSize.height / 2.0f;
float const halfWorldHieght = worldHeight / 2.0f;
// Update the position in ideal coordinates
double idealX = m_p.x + m_v.x;
double idealY = m_p.y + m_v.y;
// Account for wrap around
m_p.x = getWrappedResult(idealX, worldWidth);
m_p.y = getWrappedResult(idealY, worldHeight);
m_p.theta += m_v.theta;
m_v.x += m_a.x;
m_v.y += m_a.y;
m_v.theta += m_a.theta;
// Compute results of elastic collisions
for (list<SpaceObject *>::iterator it = m_myObjectWorldP->begin(); it != m_myObjectWorldP->end(); it++) {
SpaceObject * const SOP = (*it);
// This eventually needs to be fixed, but for now assume all
// spaceObjects are GeometrySpaceObjects
GeometrySpaceObject * thisGSOP = dynamic_cast<GeometrySpaceObject*>(this);
GeometrySpaceObject * currentGSOP = dynamic_cast<GeometrySpaceObject*>(SOP);
// Don't compare this SpaceObject with itself
if (thisGSOP != currentGSOP) {
ID2D1PathGeometry * const thisGP = thisGSOP->gGeoP();
ID2D1PathGeometry * const curGP = currentGSOP->gGeoP();
D2D1_GEOMETRY_RELATION theRelation;
thisGP->CompareWithGeometry(
(ID2D1Geometry *)curGP,
tranformMatrix,
&theRelation
);
if (theRelation != D2D1_GEOMETRY_RELATION_DISJOINT) {
// A Collision has occured.
//
// Use conservation of momentum to update
// velocities after collission here
int placeHolder = 0;
}
}
}
this->updateAcceleration();
}
Note: At the time I asked this question, the documentation I found on the MSDN site was a bit unclear regarding the inputGeometryTransform Parameter. The documentation I viewed was visible at this URL: http://msdn.microsoft.com/en-us/library/windows/desktop/dd316638(v=vs.85).aspx