// no massed rigids, at least 1 non massed
  // OL_STATIC layer and L_STAIRS, OL_TERRAIN, OL_LINE_OF_SIGHT, plus more
  // no constraints
  // no bones or skins
  public static boolean isStaticModel(String filename, MeshSource meshSource) {
    // TODO: need to handle switch nodes
    // F:\game media\skyrim\meshes\landscape\trees\treepineforest03.nif
    // F:\game media\Oblivion\meshes\Plants\FloraPrimrosePurple.NIF

    NifFile nifFile = NifToJ3d.loadNiObjects(filename, meshSource);
    return isStaticModel(nifFile);
  }
  public NBSimpleDynamicModel(String fileName, MeshSource meshSource, float forcedMass) {
    super(fileName);

    if (BulletNifModelClassifier.isSimpleDynamicModel(fileName, meshSource, forcedMass)) {
      NifFile nifFile = NifToJ3d.loadNiObjects(fileName, meshSource);

      if (nifFile != null) {
        if (nifFile.blocks.root() instanceof NiNode) {
          for (NiObject niObject : nifFile.blocks.getNiObjects()) {
            if (niObject instanceof bhkCollisionObject) {
              // TODO: check for collision being off the root node, otherwise we should be a complex
              // dynamic

              bhkCollisionObject bhkCollisionObject = (bhkCollisionObject) niObject;
              bhkRigidBody bhkRigidBody =
                  (bhkRigidBody) nifFile.blocks.get(bhkCollisionObject.body);
              int layer = bhkRigidBody.layerCopy.layer;
              if (forcedMass != 0
                  || layer == OblivionLayer.OL_CLUTTER
                  || layer == OblivionLayer.OL_PROPS) {
                bhkRigidBody.mass = forcedMass != 0 ? forcedMass : bhkRigidBody.mass;
                if (bhkRigidBody.mass != 0) {
                  if (rootDynamicBody != null) {
                    new Throwable(
                            "Multiple rigid bodies found in a simple dunamic model !!!! "
                                + fileName)
                        .printStackTrace();
                  } else {
                    rootDynamicBody =
                        new NBDynamicRigidBody(
                            new NifBulletTransformListenerDelegate(),
                            bhkCollisionObject,
                            nifFile.blocks,
                            this,
                            1.0f,
                            forcedMass);
                  }
                } else {
                  new Throwable("bhkRigidBody.mass == 0 " + this).printStackTrace();
                }
              } else {
                new Throwable("what is this layer being given to me for? " + layer + " " + this)
                    .printStackTrace();
              }
            }
          }
        }
      }
    } else {
      new Exception("NifBulletClasser.isSimpleDynamic = false " + fileName).printStackTrace();
    }
  }
  // no rigids at all
  public static boolean isNotPhysics(String filename, MeshSource meshSource) {
    NifFile nifFile = NifToJ3d.loadNiObjects(filename, meshSource);

    boolean ret = false;
    if (nifFile != null) {
      if (nifFile.blocks.root() instanceof NiNode || nifFile.blocks.root() instanceof BSTreeNode) {
        NiToJ3dData niToJ3dData = new NiToJ3dData(nifFile.blocks);

        ret = getRigidBodyCount(niToJ3dData) == 0;
      }
    }
    return ret;
  }
 // dynamics and static, but at least one dynamic
 // not sure what sort of layers to allow, statics need to be static
 // constraints can exist (storm atronach has none in death for example)
 // bones allowed for visual rendering
 // any of the go.nif files under armor, trainign dummy, ragdolls storm atronach
 public static boolean isComplexDynamic(String filename, MeshSource meshSource) {
   NifFile nifFile = NifToJ3d.loadNiObjects(filename, meshSource);
   return isStaticModel(nifFile);
 }
 // 1 only massed rigid (and is directly off root?), has 0 non massed (unless a forced mass used)
 // 1 total OL_PROP or OL_CLUTTER layer  (I think clutter can be picked and props can't?)(unless a
 // forced mass used)
 // no transform controllers
 // no constraints
 // no bones or skins
 public static boolean isSimpleDynamicModel(
     String filename, MeshSource meshSource, float forcedMass) {
   NifFile nifFile = NifToJ3d.loadNiObjects(filename, meshSource);
   return isSimpleDynamicModel(nifFile, forcedMass);
 }
 // no massed rigids, at least 1 non massed rigid
 // layers allowed OL_ANIM_STATIC, OL_STATIC
 // must have 1 OL_ANIM_STATIC
 // allowed to have transform controllers (of the OL_ANIM_STATIC ninodes), if none then a dud model
 // probably
 // no constraints
 // no bones or skins
 // E.G.   C:\game media\Fallout\meshes\clutter\briefcasedetonator
 // or C:\game media\Fallout\meshes\dungeons\office\doors
 public static boolean isKinematicModel(String filename, MeshSource meshSource) {
   NifFile nifFile = NifToJ3d.loadNiObjects(filename, meshSource);
   return isKinematicModel(nifFile);
 }