Index: src/bzfs/CustomBox.cxx
===================================================================
--- src/bzfs/CustomBox.cxx	(revision 21960)
+++ src/bzfs/CustomBox.cxx	(working copy)
@@ -360,6 +360,19 @@ void CustomBox::writeToGroupDef(GroupDefinition *g
     mats[i] = MATERIALMGR.addMaterial(&materials[i]);
   }
 
+  // set the material physicss overrides
+  bool drvthru[FaceCount];
+  bool shtthru[FaceCount];
+  bool ricos[FaceCount];
+  int  fullPhydrv[FaceCount];
+  for (i = 0; i < FaceCount; i++) {
+    const BzMaterial* mat = mats[i];
+    drvthru[i] = drivethrough[i] || mat->getDriveThrough();
+    shtthru[i] = shootthrough[i] || mat->getShootThrough();
+    ricos[i]   = ricochets[i]    || mat->getRicochet();
+    fullPhydrv[i] = (phydrv[i] != -1) ? phydrv[i] : mat->getPhyDrv();
+  }
+
   // the index arrays
   std::vector<int> iv;
   std::vector<int> it;
@@ -369,43 +382,43 @@ void CustomBox::writeToGroupDef(GroupDefinition *g
   iv.clear(); it.clear();
   iv.push_back(1); iv.push_back(2); iv.push_back(6); iv.push_back(5);
   it.push_back(0); it.push_back(1); it.push_back(2); it.push_back(3);
-  mesh->addFace(iv, in, it, mats[XP], phydrv[XP], false, false,
-		drivethrough[XP], shootthrough[XP], ricochets[XP], false);
+  mesh->addFace(iv, in, it, mats[XP], fullPhydrv[XP], false, false,
+		drvthru[XP], shtthru[XP], ricos[XP], false);
 
   // XN
   iv.clear(); it.clear();
   iv.push_back(3); iv.push_back(0); iv.push_back(4); iv.push_back(7);
   it.push_back(4); it.push_back(5); it.push_back(6); it.push_back(7);
-  mesh->addFace(iv, in, it, mats[XN], phydrv[XN], false, false,
-		drivethrough[XN], shootthrough[XN], ricochets[XN], false);
+  mesh->addFace(iv, in, it, mats[XN], fullPhydrv[XN], false, false,
+		drvthru[XN], shtthru[XN], ricos[XN], false);
 
   // YP
   iv.clear(); it.clear();
   iv.push_back(2); iv.push_back(3); iv.push_back(7); iv.push_back(6);
   it.push_back(8); it.push_back(9); it.push_back(10); it.push_back(11);
-  mesh->addFace(iv, in, it, mats[YP], phydrv[YP], false, false,
-		drivethrough[YP], shootthrough[YP], ricochets[YP], false);
+  mesh->addFace(iv, in, it, mats[YP], fullPhydrv[YP], false, false,
+		drvthru[YP], shtthru[YP], ricos[YP], false);
 
   // YN
   iv.clear(); it.clear();
   iv.push_back(0); iv.push_back(1); iv.push_back(5); iv.push_back(4);
   it.push_back(12); it.push_back(13); it.push_back(14); it.push_back(15);
-  mesh->addFace(iv, in, it, mats[YN], phydrv[YN], false, false,
-		drivethrough[YN], shootthrough[YN], ricochets[YN], false);
+  mesh->addFace(iv, in, it, mats[YN], fullPhydrv[YN], false, false,
+		drvthru[YN], shtthru[YN], ricos[YN], false);
 
   // ZP
   iv.clear(); it.clear();
   iv.push_back(4); iv.push_back(5); iv.push_back(6); iv.push_back(7);
   it.push_back(16); it.push_back(17); it.push_back(18); it.push_back(19);
-  mesh->addFace(iv, in, it, mats[ZP], phydrv[ZP], false, false,
-		drivethrough[ZP], shootthrough[ZP], ricochets[ZP], false);
+  mesh->addFace(iv, in, it, mats[ZP], fullPhydrv[ZP], false, false,
+		drvthru[ZP], shtthru[ZP], ricos[ZP], false);
 
   // ZN
   iv.clear(); it.clear();
   iv.push_back(1); iv.push_back(0); iv.push_back(3); iv.push_back(2);
   it.push_back(20); it.push_back(21); it.push_back(22); it.push_back(23);
-  mesh->addFace(iv, in, it, mats[ZN], phydrv[ZN], false, false,
-		drivethrough[ZN], shootthrough[ZN], ricochets[ZN], false);
+  mesh->addFace(iv, in, it, mats[ZN], fullPhydrv[ZN], false, false,
+		drvthru[ZN], shtthru[ZN], ricos[ZN], false);
 
   // to be or not to be...
   if (mesh->isValid()) {
Index: src/bzfs/ParseMaterial.cxx
===================================================================
--- src/bzfs/ParseMaterial.cxx	(revision 21960)
+++ src/bzfs/ParseMaterial.cxx	(working copy)
@@ -20,6 +20,7 @@
 
 /* common implementation headers */
 #include "ParseColor.h"
+#include "PhysicsDriver.h"
 #include "TextureMatrix.h"
 #include "DynamicColor.h"
 
@@ -247,6 +248,48 @@ bool parseMaterials(const char* cmd, std::istream&
       materials[i].clearShaders();
     }
   }
+  else if (strcasecmp(cmd, "phydrv") == 0) {
+    std::string drvname;
+    if (!(input >> drvname)) {
+      std::cout << "missing Physics Driver parameter" << std::endl;
+      return false;
+    }
+    const int phydrv = PHYDRVMGR.findDriver(drvname);
+    if ((phydrv == -1) && (drvname != "-1")) {
+      std::cout << "couldn't find PhysicsDriver: " << drvname << std::endl;
+    }
+    else {
+      for (i = 0; i < materialCount; i++) {
+        materials[i].setPhyDrv(phydrv);
+      }
+    }
+  }
+  else if (strcasecmp(cmd, "smoothbounce") == 0) {
+    for (i = 0; i < materialCount; i++) {
+      materials[i].setSmoothBounce(true);
+    }
+  }
+  else if (strcasecmp(cmd, "noclusters") == 0) {
+    for (i = 0; i < materialCount; i++) {
+      materials[i].setNoClusters(true);
+    }
+  }
+  else if (strcasecmp(cmd, "drivethrough") == 0) {
+    for (i = 0; i < materialCount; i++) {
+      materials[i].setDriveThrough(true);
+    }
+  }
+  else if (strcasecmp(cmd, "shootthrough") == 0) {
+    for (i = 0; i < materialCount; i++) {
+      materials[i].setShootThrough(true);
+    }
+  }
+  else if (strcasecmp(cmd, "passable") == 0) {
+    for (i = 0; i < materialCount; i++) {
+      materials[i].setDriveThrough(true);
+      materials[i].setShootThrough(true);
+    }
+  }
   else {
     return false;
   }
Index: src/bzfs/CustomPyramid.cxx
===================================================================
--- src/bzfs/CustomPyramid.cxx	(revision 21960)
+++ src/bzfs/CustomPyramid.cxx	(working copy)
@@ -385,6 +385,20 @@ void CustomPyramid::writeToGroupDef(GroupDefinitio
     mats[i] = MATERIALMGR.addMaterial(&materials[i]);
   }
 
+  // set the material physicss overrides
+  bool drvthru[FaceCount];
+  bool shtthru[FaceCount];
+  bool ricos[FaceCount];
+  int  fullPhydrv[FaceCount];
+  for (i = 0; i < FaceCount; i++) {
+    const BzMaterial* mat = mats[i];
+    drvthru[i] = drivethrough[i] || mat->getDriveThrough();
+    shtthru[i] = shootthrough[i] || mat->getShootThrough();
+    ricos[i]   = ricochets[i]    || mat->getRicochet();
+    fullPhydrv[i] = (phydrv[i] != -1) ? phydrv[i] : mat->getPhyDrv();
+  }
+
+
   // the index arrays
   std::vector<int> iv;
   std::vector<int> it;
@@ -394,36 +408,36 @@ void CustomPyramid::writeToGroupDef(GroupDefinitio
   iv.clear(); it.clear();
   iv.push_back(1); iv.push_back(2); iv.push_back(4);
   it.push_back(0); it.push_back(1); it.push_back(2);
-  mesh->addFace(iv, in, it, mats[XP], phydrv[XP], false, false,
-		drivethrough[XP], shootthrough[XP], ricochets[XP],  false);
+  mesh->addFace(iv, in, it, mats[XP], fullPhydrv[XP], false, false,
+		drvthru[XP], shtthru[XP], ricos[XP],  false);
 
   // XN
   iv.clear(); it.clear();
   iv.push_back(3); iv.push_back(0); iv.push_back(4);
   it.push_back(3); it.push_back(4); it.push_back(5);
-  mesh->addFace(iv, in, it, mats[XN], phydrv[XN], false, false,
-		drivethrough[XN], shootthrough[XN], ricochets[XN], false);
+  mesh->addFace(iv, in, it, mats[XN], fullPhydrv[XN], false, false,
+		drvthru[XN], shtthru[XN], ricos[XN], false);
 
   // YP
   iv.clear(); it.clear();
   iv.push_back(2); iv.push_back(3); iv.push_back(4);
   it.push_back(6); it.push_back(7); it.push_back(8);
-  mesh->addFace(iv, in, it, mats[YP], phydrv[YP], false, false,
-		drivethrough[YP], shootthrough[YP], ricochets[XN], false);
+  mesh->addFace(iv, in, it, mats[YP], fullPhydrv[YP], false, false,
+		drvthru[YP], shtthru[YP], ricos[XN], false);
 
   // YN
   iv.clear(); it.clear();
   iv.push_back(0); iv.push_back(1); iv.push_back(4);
   it.push_back(9); it.push_back(10); it.push_back(11);
-  mesh->addFace(iv, in, it, mats[YN], phydrv[YN], false, false,
-		drivethrough[YN], shootthrough[YN], ricochets[YN], false);
+  mesh->addFace(iv, in, it, mats[YN], fullPhydrv[YN], false, false,
+		drvthru[YN], shtthru[YN], ricos[YN], false);
 
   // ZN
   iv.clear(); it.clear();
   iv.push_back(1); iv.push_back(0); iv.push_back(3); iv.push_back(2);
   it.push_back(12); it.push_back(13); it.push_back(14); it.push_back(15);
-  mesh->addFace(iv, in, it, mats[ZN], phydrv[ZN], false, false,
-		drivethrough[ZN], shootthrough[ZN], ricochets[ZN], false);
+  mesh->addFace(iv, in, it, mats[ZN], fullPhydrv[ZN], false, false,
+		drvthru[ZN], shtthru[ZN], ricos[ZN], false);
 
   // to be or not to be...
   if (mesh->isValid()) {
Index: src/bzfs/CustomMeshFace.cxx
===================================================================
--- src/bzfs/CustomMeshFace.cxx	(revision 21960)
+++ src/bzfs/CustomMeshFace.cxx	(working copy)
@@ -129,9 +129,16 @@ bool CustomMeshFace::read(const char *cmd, std::is
 void CustomMeshFace::write(MeshObstacle *mesh) const
 {
   const BzMaterial* matref = MATERIALMGR.addMaterial(&material);
-  mesh->addFace(vertices, normals, texcoords, matref, phydrv,
-		noclusters, smoothBounce, driveThrough, shootThrough, ricochet,
+  const int fullPhydrv = (phydrv != -1) ? phydrv : matref->getPhyDrv();
+
+  mesh->addFace(vertices, normals, texcoords, matref, fullPhydrv,
+		noclusters   || matref->getNoClusters(),
+		smoothBounce || matref->getSmoothBounce(),
+		driveThrough || matref->getDriveThrough(),
+		shootThrough || matref->getShootThrough(),
+		ricochet     || matref->getRicochet(),
 		true /* triangulate if required */);
+
   return;
 }
 
Index: src/game/BzMaterial.cxx
===================================================================
--- src/game/BzMaterial.cxx	(revision 21960)
+++ src/game/BzMaterial.cxx	(working copy)
@@ -265,6 +265,13 @@ void BzMaterial::reset()
   shaders = NULL;
   shaderCount = 0;
 
+  phydrv = -1;
+  driveThrough = false;
+  shootThrough = false;
+  ricochet = false;
+  smoothBounce = false;
+  noClusters = false;
+
   referenced = false;
 
   return;
@@ -343,6 +350,13 @@ BzMaterial& BzMaterial::operator=(const BzMaterial
     shaders[i] = m.shaders[i];
   }
 
+  phydrv = m.phydrv;
+  driveThrough = m.driveThrough;
+  shootThrough = m.shootThrough;
+  ricochet = m.ricochet;
+  smoothBounce = m.smoothBounce;
+  noClusters = m.noClusters;
+
   return *this;
 }
 
@@ -387,6 +401,14 @@ bool BzMaterial::operator==(const BzMaterial& m) c
     }
   }
 
+  if (phydrv       != m.phydrv)       { return false; }
+  if (driveThrough != m.driveThrough) { return false; }
+  if (shootThrough != m.shootThrough) { return false; }
+  if (ricochet     != m.ricochet)     { return false; }
+  if (smoothBounce != m.smoothBounce) { return false; }
+  if (noClusters   != m.noClusters)   { return false; }
+
+
   return true;
 }
 
@@ -948,6 +970,42 @@ void BzMaterial::clearShaders()
 }
 
 
+void BzMaterial::setPhyDrv(int value)
+{
+  phydrv = value;
+}
+
+
+void BzMaterial::setDriveThrough(bool value)
+{
+  driveThrough = value;
+}
+
+
+void BzMaterial::setShootThrough(bool value)
+{
+  shootThrough = value;
+}
+
+
+void BzMaterial::setRicochet(bool value)
+{
+  ricochet = value;
+}
+
+
+void BzMaterial::setSmoothBounce(bool value)
+{
+  smoothBounce = value;
+}
+
+
+void BzMaterial::setNoClusters(bool value)
+{
+  noClusters = value;
+}
+
+
 /****************************************************************************/
 //
 // Parameter retrieval
Index: include/BzMaterial.h
===================================================================
--- include/BzMaterial.h	(revision 21960)
+++ include/BzMaterial.h	(working copy)
@@ -85,6 +85,13 @@ class BzMaterial {
     void setShader(const std::string&);
     void clearShaders(); // remove all shaders
 
+    void setPhyDrv(int);
+    void setDriveThrough(bool);
+    void setShootThrough(bool);
+    void setRicochet(bool);
+    void setSmoothBounce(bool);
+    void setNoClusters(bool);
+
     //
     // Parameter getting
     //
@@ -120,6 +127,13 @@ class BzMaterial {
     int getShaderCount() const;
     const std::string& getShader(int) const;
 
+    int  getPhyDrv()       const { return phydrv;       }
+    bool getDriveThrough() const { return driveThrough; }
+    bool getShootThrough() const { return shootThrough; }
+    bool getRicochet()     const { return ricochet;     }
+    bool getSmoothBounce() const { return smoothBounce; }
+    bool getNoClusters()   const { return noClusters;   }
+
     //
     // Utilities
     //
@@ -184,6 +198,13 @@ class BzMaterial {
     } ShaderInfo;
     ShaderInfo* shaders;
 
+    int  phydrv;
+    bool driveThrough;
+    bool shootThrough;
+    bool ricochet;
+    bool smoothBounce;
+    bool noClusters;
+
   private:
     static std::string nullString;
     static BzMaterial defaultMaterial;
