Browse Source

Updated to newest ODE from svn.

Lasse Öörni 14 years ago
parent
commit
8b61a23cd0

+ 1 - 1
Docs/Urho3D.dox

@@ -65,7 +65,7 @@ Urho3D uses the following third-party libraries:
 - GLFW 3.0 WIP (http://www.glfw.org/)
 - kNet (https://bitbucket.org/clb/knet)
 - Open Asset Import Library, svn rev 1062 (http://assimp.sourceforge.net/)
-- Open Dynamics %Engine, svn rev 1806 (http://www.ode.org/)
+- Open Dynamics %Engine, svn rev 1846 (http://www.ode.org/)
 - PortAudio V19 (http://www.portaudio.com/)
 - StanHull (http://codesuppository.blogspot.com/2006/03/john-ratcliffs-code-suppository-blog.html)
 - stb_image 1.29 (http://nothings.org/)

+ 1 - 0
Engine/Graphics/View.cpp

@@ -829,6 +829,7 @@ void View::GetLitBatches(Drawable* drawable, LightBatchQueue& lightQueue)
         Pass* pass = 0;
         
         // Check for lit base pass. Because it uses the replace blend mode, it must be ensured to be the first light
+        // Also vertex lighting requires the non-lit base pass, so skip if any vertex lights
         if (light == firstLight && drawable->GetVertexLights().Empty() && !drawable->HasBasePass(i))
         {
             pass = tech->GetPass(PASS_LITBASE);

+ 1 - 1
Readme.txt

@@ -40,7 +40,7 @@ Urho3D uses the following third-party libraries:
 - GLFW 3.0 WIP (http://www.glfw.org/)
 - kNet (https://bitbucket.org/clb/knet)
 - Open Asset Import Library, svn rev 1062 (http://assimp.sourceforge.net/)
-- Open Dynamics Engine, svn rev 1806 (http://www.ode.org/)
+- Open Dynamics Engine, svn rev 1846 (http://www.ode.org/)
 - PortAudio V19 (http://www.portaudio.com/)
 - StanHull (http://codesuppository.blogspot.com/2006/03/
   john-ratcliffs-code-suppository-blog.html)

+ 1 - 0
ThirdParty/ODE/include/ode/common.h

@@ -33,6 +33,7 @@ extern "C" {
 
 #define PURE_INLINE static __inline
 
+
 /* configuration stuff */
 
 /* constants */

+ 31 - 2
ThirdParty/ODE/ode/src/capsule.cpp

@@ -160,6 +160,20 @@ int dCollideCapsuleSphere (dxGeom *o1, dxGeom *o2, int flags,
   return dCollideSpheres (p,ccyl->radius,o2->final_posr->pos,sphere->radius,contact);
 }
 
+// use this instead of dCollideSpheres if the spheres are at the same point, 
+//  but the normal is known (e.g. in capsule-box collision)
+int dCollideSpheresZeroDist (dVector3 p1, dReal r1, dVector3 p2, dReal r2, 
+                             dVector3 normal, dContactGeom *c) {
+  c->normal[0] = normal[0];
+  c->normal[1] = normal[1];
+  c->normal[2] = normal[2];
+  c->depth  = r1 + r2;
+  dReal k = REAL(0.5) * (r2 - r1);
+  c->pos[0] = p1[0] + c->normal[0]*k;
+  c->pos[1] = p1[1] + c->normal[1]*k;
+  c->pos[2] = p1[2] + c->normal[2]*k;
+  return 1;
+}
 
 int dCollideCapsuleBox (dxGeom *o1, dxGeom *o2, int flags,
 			  dContactGeom *contact, int skip)
@@ -197,8 +211,23 @@ int dCollideCapsuleBox (dxGeom *o1, dxGeom *o2, int flags,
   dVector3 pl,pb;
   dClosestLineBoxPoints (p1,p2,c,R,side,pl,pb);
 
-  // generate contact point
-  return dCollideSpheres (pl,radius,pb,0,contact);
+  // if the capsule is penetrated further than radius 
+  //  than pl and pb are equal -> unknown normal
+  // use vector to center of box as normal
+#ifdef dSINGLE
+  dReal mindist = REAL(1e-9);
+#else
+  dReal mindist = REAL(1e-18);
+#endif
+  if (dCalcPointsDistance3(pl, pb)<mindist) {
+    dVector3 normal; // pb-c (vector from center of box to pb)
+    for (int i=0; i<3; i++) normal[i] = pb[i]-c[i];
+    dSafeNormalize3(normal);
+    return dCollideSpheresZeroDist (pl,radius,pb,0,normal,contact);
+  } else {
+    // generate contact point
+    return dCollideSpheres (pl,radius,pb,0,contact);
+  }
 }
 
 

+ 1 - 1
ThirdParty/ODE/ode/src/collision_sapspace.cpp

@@ -243,7 +243,7 @@ static void collideGeomsNoAABBs( dxGeom *g1, dxGeom *g2, void *data, dNearCallba
 
 	// test if the category and collide bitfields match
     // Urho3D: modified to allow easier collision exclusion
-    if ((!(g1->category_bits & g2->collide_bits)) || (!(g2->category_bits & g1->collide_bits)))
+    if (!(g1->category_bits & g2->collide_bits) || !(g2->category_bits & g1->collide_bits))
         return;
 
 	dReal *bounds1 = g1->aabb;

+ 2 - 2
ThirdParty/ODE/ode/src/collision_space_internal.h

@@ -47,7 +47,7 @@ stuff common to all spaces
 // NOTE: this assumes that the geom AABBs are valid on entry
 // and that both geoms are enabled.
 
-static void collideAABBs (dxGeom *g1, dxGeom *g2,
+static inline void collideAABBs (dxGeom *g1, dxGeom *g2,
 			  void *data, dNearCallback *callback)
 {
   dIASSERT((g1->gflags & GEOM_AABB_BAD)==0);
@@ -58,7 +58,7 @@ static void collideAABBs (dxGeom *g1, dxGeom *g2,
 
   // test if the category and collide bitfields match
   // Urho3D: modified to allow easier collision exclusion
-  if ((!(g1->category_bits & g2->collide_bits)) || (!(g2->category_bits & g1->collide_bits)))
+  if (!(g1->category_bits & g2->collide_bits) || !(g2->category_bits & g1->collide_bits))
     return;
 
   // if the bounding boxes are disjoint then don't do anything

+ 1 - 1
ThirdParty/ODE/ode/src/collision_trimesh_internal.h

@@ -341,7 +341,7 @@ struct dxTriMesh : public dxGeom{
 #if dTRIMESH_OPCODE
 
 	enum {
-		MERGE_NORMALS__SPHERE_DEFAULT = MERGE_CONTACTS_FULLY,
+		MERGE_NORMALS__SPHERE_DEFAULT = DONT_MERGE_CONTACTS,
 	};
 	bool controlGeometry_SetMergeSphereContacts(int dataValue);
 	bool controlGeometry_GetMergeSphereContacts(int &returnValue);

+ 14 - 14
ThirdParty/ODE/ode/src/collision_trimesh_opcode.cpp

@@ -643,21 +643,21 @@ bool dxTriMesh::controlGeometry_SetMergeSphereContacts(int dataValue)
 
 bool dxTriMesh::controlGeometry_GetMergeSphereContacts(int &returnValue)
 {
-	if (SphereContactsMergeOption = DONT_MERGE_CONTACTS) {
-		returnValue = dGeomColliderMergeContactsValue_None;
-	}
-	else if (SphereContactsMergeOption = MERGE_CONTACT_NORMALS) {
-		returnValue = dGeomColliderMergeContactsValue_Normals;
-	}
-	else if (SphereContactsMergeOption = MERGE_CONTACTS_FULLY) {
-		returnValue = dGeomColliderMergeContactsValue_Full;
-	}
-	else {
-		dIASSERT(false && "Internal error: unexpected contact merge option field value");
-		return false;
-	}
+    if (SphereContactsMergeOption == DONT_MERGE_CONTACTS) {
+        returnValue = dGeomColliderMergeContactsValue_None;
+    }
+    else if (SphereContactsMergeOption == MERGE_CONTACT_NORMALS) {
+        returnValue = dGeomColliderMergeContactsValue_Normals;
+    }
+    else if (SphereContactsMergeOption == MERGE_CONTACTS_FULLY) {
+        returnValue = dGeomColliderMergeContactsValue_Full;
+    }
+    else {
+        dIASSERT(false && "Internal error: unexpected contact merge option field value");
+        return false;
+    }
 
-	return true;
+    return true;
 }
 
 int dxTriMesh::AABBTest(dxGeom* g, dReal aabb[6]){

+ 37 - 16
ThirdParty/ODE/ode/src/collision_trimesh_sphere.cpp

@@ -29,6 +29,10 @@
 #include "config.h"
 #include "collision_util.h"
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #if dTRIMESH_ENABLED
 #include "collision_trimesh_internal.h"
 
@@ -411,14 +415,12 @@ int dCollideSTL(dxGeom* g1, dxGeom* SphereGeom, int Flags, dContactGeom* Contact
 			Contact->depth = Depth * dirProj;
 			//Contact->depth = Radius - side; // (mg) penetration depth is distance along normal not shortest distance
 			
-			if (TriMesh->SphereContactsMergeOption != MERGE_CONTACTS_FULLY) {
-				Contact->g1 = TriMesh;
-				Contact->g2 = SphereGeom;
-
-				Contact->side2 = -1;
-			}
+			// We need to set these unconditionally, as the merging may fail! - Bram
+			Contact->g1 = TriMesh;
+			Contact->g2 = SphereGeom;
+			Contact->side2 = -1;
 
-            Contact->side1 = TriIndex;
+			Contact->side1 = TriIndex;
 
 			OutTriCount++;
 		}
@@ -439,7 +441,8 @@ int dCollideSTL(dxGeom* g1, dxGeom* SphereGeom, int Flags, dContactGeom* Contact
 					normal[0] = Contact->normal[0] * Contact->depth;
 					normal[1] = Contact->normal[1] * Contact->depth;
 					normal[2] = Contact->normal[2] * Contact->depth;
-	                
+					normal[3] = REAL(0.0);
+
 					int TriIndex = Contact->side1;
 
 					for (int i = 1; i < OutTriCount; i++){
@@ -461,14 +464,32 @@ int dCollideSTL(dxGeom* g1, dxGeom* SphereGeom, int Flags, dContactGeom* Contact
 					Contact->pos[0] = pos[0] / OutTriCount;
 					Contact->pos[1] = pos[1] / OutTriCount;
 					Contact->pos[2] = pos[2] / OutTriCount;
-					
-					// Remember to divide in square space.
-					Contact->depth = dSqrt(dCalcVectorDot3(normal, normal) / OutTriCount);
-
-					if (Contact->depth > dEpsilon) { // otherwise the normal is too small
-						dVector3Copy(normal, Contact->normal);
-						dNormalize3(Contact->normal);
-					} // otherwise original Contact's normal would be used and it should be already normalized
+                    
+					if ( !dSafeNormalize3(normal) )
+						return OutTriCount;	// Cannot merge in this pathological case
+                    
+					// Using a merged normal, means that for each intersection, this new normal will be less effective in solving the intersection.
+					// That is why we need to correct this by increasing the depth for each intersection.
+					// The maximum of the adjusted depths is our newly merged depth value - Bram.
+
+					dReal mergedDepth = REAL(0.0);
+					dReal minEffectiveness = REAL(0.5);
+					for ( int i = 0; i < OutTriCount; ++i )
+					{
+						dContactGeom* TempContact = SAFECONTACT(Flags, Contacts, i, Stride);
+						dReal effectiveness = dCalcVectorDot3(normal, TempContact->normal);
+						if ( effectiveness < dEpsilon )
+							return OutTriCount; // Cannot merge this pathological case
+						// Cap our adjustment for the new normal to a factor 2, meaning a 60 deg change in normal.
+						effectiveness = ( effectiveness < minEffectiveness ) ? minEffectiveness : effectiveness;
+						dReal adjusted = TempContact->depth / effectiveness;
+						mergedDepth = ( mergedDepth < adjusted ) ? adjusted : mergedDepth;
+					}
+					Contact->depth = mergedDepth;
+					Contact->normal[0] = normal[0];
+					Contact->normal[1] = normal[1];
+					Contact->normal[2] = normal[2];
+					Contact->normal[3] = normal[3];
 				}
 
 				return 1;

+ 1 - 1
ThirdParty/ODE/ode/src/joints/joint.h

@@ -148,7 +148,7 @@ struct dxJoint : public dObject
     virtual dJointType type() const = 0;
     virtual size_t size() const = 0;
 
-    /// %Set values which are relative with respect to bodies.
+    /// Set values which are relative with respect to bodies.
     /// Each dxJoint should redefine it if needed.
     virtual void setRelativeValues() {};
 

+ 1 - 1
ThirdParty/ODE/ode/src/matrix.cpp

@@ -286,7 +286,7 @@ void _dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip, void *tm
     alpha1 = alphanew;
     alphanew = alpha2 - (W21*W21)*dee;
     dee /= alphanew;
-    dReal gamma2 = W21 * dee;
+    //dReal gamma2 = W21 * dee;
     alpha2 = alphanew;
     dReal k1 = REAL(1.0) - W21*gamma1;
     dReal k2 = W21*gamma1*W11 - W21;

+ 1 - 1
ThirdParty/ODE/ode/src/step.cpp

@@ -366,7 +366,7 @@ void dInternalStepIsland_x2 (dxWorldProcessContext *context,
               jicurr->joint = j;
               --jicurr;
             } else if (jicurr->info.nub > 0) { // A mixed case
-              if (mix_end = lcp_end) { // no lcp infos yet - just move to opposite side of mixed-s
+              if (mix_end == lcp_end) { // no lcp infos yet - just move to opposite side of mixed-s
                 dJointWithInfo1 *jimixend = jointiinfos + mix_end;
                 lcp_end = mix_end = mix_end + 1;
                 jimixend->info = jicurr->info;