diff --git a/gen/SkinData.cpp b/gen/SkinData.cpp
index 540d1b34e6e5e165328c8db3734c6e7d76e75c53..07ca9a475778f2eb595278cfb30f30e672122d56 100644
--- a/gen/SkinData.cpp
+++ b/gen/SkinData.cpp
@@ -6,7 +6,7 @@ All rights reserved.  Please see niflib.h for licence. */
 using namespace Niflib;
 
 //Constructor
-SkinData::SkinData() : scale(0.0f), numVertices((ushort)0) {};
+SkinData::SkinData() : scale(0.0f), boundingSphereRadius(0.0f), numVertices((ushort)0) {};
 
 //Destructor
 SkinData::~SkinData() {};
diff --git a/gen/SkinData.h b/gen/SkinData.h
index f33f32b2182f6e7c4f838127592e7dae96e88c05..bf55b03b0d24b870d2ab280156b4ccb723645a56 100644
--- a/gen/SkinData.h
+++ b/gen/SkinData.h
@@ -33,11 +33,15 @@ struct NIFLIB_API SkinData {
 	 */
 	float scale;
 	/*!
-	 * This has been verified not to be a normalized quaternion.  They may or
-	 * may not be related to each other so their specification as an array of
-	 * 4 floats may be misleading.
+	 * Translation offset of a bounding sphere holding all vertices. (Note
+	 * that its a Sphere Containing Axis Aligned Box not a minimum volume
+	 * Sphere)
 	 */
-	array<float,4> unknown4Floats;
+	Vector3 boundingSphereOffset;
+	/*!
+	 * Radius for bounding sphere holding all vertices.
+	 */
+	float boundingSphereRadius;
 	/*!
 	 * Number of weighted vertices.
 	 */
diff --git a/gen/obj_impl.cpp b/gen/obj_impl.cpp
index a6d907e3c68e85f52165ca1b969d6f5ccd0a1bd0..cd507bb0f8e14b38bcc149f347896da295249782 100644
--- a/gen/obj_impl.cpp
+++ b/gen/obj_impl.cpp
@@ -10442,9 +10442,8 @@ void NiSkinData::InternalRead( istream& in, list<uint> & link_stack, unsigned in
 		NifStream( boneList[i1].rotation, in, version );
 		NifStream( boneList[i1].translation, in, version );
 		NifStream( boneList[i1].scale, in, version );
-		for (uint i2 = 0; i2 < 4; i2++) {
-			NifStream( boneList[i1].unknown4Floats[i2], in, version );
-		};
+		NifStream( boneList[i1].boundingSphereOffset, in, version );
+		NifStream( boneList[i1].boundingSphereRadius, in, version );
 		NifStream( boneList[i1].numVertices, in, version );
 		boneList[i1].vertexWeights.resize(boneList[i1].numVertices);
 		for (uint i2 = 0; i2 < boneList[i1].vertexWeights.size(); i2++) {
@@ -10475,9 +10474,8 @@ void NiSkinData::InternalWrite( ostream& out, map<NiObjectRef,uint> link_map, un
 		NifStream( boneList[i1].rotation, out, version );
 		NifStream( boneList[i1].translation, out, version );
 		NifStream( boneList[i1].scale, out, version );
-		for (uint i2 = 0; i2 < 4; i2++) {
-			NifStream( boneList[i1].unknown4Floats[i2], out, version );
-		};
+		NifStream( boneList[i1].boundingSphereOffset, out, version );
+		NifStream( boneList[i1].boundingSphereRadius, out, version );
 		NifStream( boneList[i1].numVertices, out, version );
 		for (uint i2 = 0; i2 < boneList[i1].vertexWeights.size(); i2++) {
 			NifStream( boneList[i1].vertexWeights[i2].index, out, version );
@@ -10501,13 +10499,8 @@ std::string NiSkinData::InternalAsString( bool verbose ) const {
 		out << "    Rotation:  " << boneList[i1].rotation << endl;
 		out << "    Translation:  " << boneList[i1].translation << endl;
 		out << "    Scale:  " << boneList[i1].scale << endl;
-		for (uint i2 = 0; i2 < 4; i2++) {
-			if ( !verbose && ( i2 > MAXARRAYDUMP ) ) {
-				out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl;
-				break;
-			};
-			out << "      Unknown 4 Floats[" << i2 << "]:  " << boneList[i1].unknown4Floats[i2] << endl;
-		};
+		out << "    Bounding Sphere Offset:  " << boneList[i1].boundingSphereOffset << endl;
+		out << "    Bounding Sphere Radius:  " << boneList[i1].boundingSphereRadius << endl;
 		out << "    Num Vertices:  " << boneList[i1].numVertices << endl;
 		for (uint i2 = 0; i2 < boneList[i1].vertexWeights.size(); i2++) {
 			out << "      Index:  " << boneList[i1].vertexWeights[i2].index << endl;
diff --git a/niflib.h b/niflib.h
index 3fca3a49799d756b5aa9222e2421dc1c2403b7b3..79784c8540fdeaddcec59b752859d67318f77cbd 100644
--- a/niflib.h
+++ b/niflib.h
@@ -264,6 +264,27 @@ NIFLIB_API void SendNifTreeToBindPos( const Ref<NiNode> & root );
  */
 NIFLIB_API Ref<NiObject> CreateBlock( string block_type );
 
+
+/*!
+* Creates a new block of the given type and returns a reference to it
+* \param T – The type of block you want to create.  Ex. NiNode, NiTriShapeData, NiParticleSystemController, etc.
+* \return This function will return a newly created block of the requested type.
+* 
+* <b>Example:</b> 
+* \code
+* NiNodeRef my_block = CreateNiObject<NiNode>();
+* \endcode
+* 
+* sa BlocksInMemory
+*/
+#ifndef SWIG
+template<typename T>
+inline Ref<T> CreateNiObject() {
+   return DynamicCast<T>(CreateBlock(T::TypeConst().GetTypeName()));
+}
+#endif
+
+
 /*!
  * Returns whether the requested version is supported.
  * \param version The version of the nif format to test for availablity.
diff --git a/obj/NiAVObject.cpp b/obj/NiAVObject.cpp
index 409e7002670e05d3f2aacdcc0474fe0f7960815c..c7d47443bd1d71178536663ae58f17fb7aa77e45 100644
--- a/obj/NiAVObject.cpp
+++ b/obj/NiAVObject.cpp
@@ -168,6 +168,24 @@ bool NiAVObject::GetHidden()
    return (bool)NIFLIB_GET_FLAG(flags, 0, 0x01);
 }
 
+Ref<NiCollisionData > NiAVObject::GetCollisionData() const {
+   return collisionData;
+}
+
+void NiAVObject::SetCollisionData( Ref<NiCollisionData > value ) {
+   collisionData = value;
+}
+
+
+ef<NiCollisionObject > NiAVObject::GetCollisionObject() const {
+
+  return collisionObject;
+}
+
+void NiAVObject::SetCollisionObject( Ref<NiCollisionObject > value ) {
+   collisionObject = value;
+}
+
 void NiAVObject::SetHidden(bool value)
 {
    flags = NIFLIB_MASK_FLAG(flags, value, 0, 0x01);
diff --git a/obj/NiAVObject.h b/obj/NiAVObject.h
index 55e37a30e9dad44fd25e8c0e2476e778193405c7..159311d73c1d85cc53b0cfd3c5e0fbc19133c65a 100644
--- a/obj/NiAVObject.h
+++ b/obj/NiAVObject.h
@@ -102,6 +102,12 @@ public:
 	Ref<NiCollisionObject > GetCollisionObject() const;
 	void SetCollisionObject( Ref<NiCollisionObject> value );
 
+   /*!
+   * Bounding box: refers to NiCollisionData
+   */
+   Ref<NiCollisionData > GetCollisionData() const;
+   void SetCollisionData( Ref<NiCollisionData> value );
+
    bool GetHidden();
    void SetHidden(bool value);
 
@@ -113,6 +119,7 @@ public:
    CollisionType GetCollision();
    void SetCollsion(CollisionType value);
 
+
 protected:
 	NiNode * parent;
 	NI_A_V_OBJECT_MEMBERS
diff --git a/obj/NiSkinData.cpp b/obj/NiSkinData.cpp
index 0bf29e75b5f9c06f00b06c89861a3f1c4f46a6e3..877b4fc2be3e9cf7b0715feba501efe8bd5d06b4 100644
--- a/obj/NiSkinData.cpp
+++ b/obj/NiSkinData.cpp
@@ -67,10 +67,8 @@ void NiSkinData::SetBoneWeights( uint bone_index, const vector<SkinWeight> & n,
 	}
 
 	boneList[bone_index].vertexWeights = n;
-	boneList[bone_index].unknown4Floats[0] = center.x;
-	boneList[bone_index].unknown4Floats[1] = center.y;
-	boneList[bone_index].unknown4Floats[2] = center.z;
-	boneList[bone_index].unknown4Floats[3] = radius;
+   boneList[bone_index].boundingSphereOffset = center;
+   boneList[bone_index].boundingSphereRadius = radius;
 }
 
 Matrix44 NiSkinData::GetOverallTransform() const {
@@ -121,4 +119,4 @@ NiSkinData::NiSkinData( const Ref<NiTriBasedGeom> & owner ) {
 		//Store result
 		res_mat.Decompose( boneList[i].translation, boneList[i].rotation, boneList[i].scale );
 	}
-}
\ No newline at end of file
+}
diff --git a/obj/NiSkinData.h b/obj/NiSkinData.h
index 9d7cc5ff809d383f49828b97e18c8ece009da57a..101ead61a12550e28259b5784e6efc8502f2a4d8 100644
--- a/obj/NiSkinData.h
+++ b/obj/NiSkinData.h
@@ -51,7 +51,7 @@ public:
 	uint GetBoneCount() const;
 	Matrix44 GetBoneTransform( uint bone_index ) const;
 	vector<SkinWeight> GetBoneWeights( uint bone_index ) const;
-	void SetBoneWeights( uint bone_index, const vector<SkinWeight> & n, Vector3 center, float radius );
+   void SetBoneWeights( uint bone_index, const vector<SkinWeight> & n, Vector3 center, float radius );
 
 protected:
 	NI_SKIN_DATA_MEMBERS
diff --git a/obj/NiSkinInstance.cpp b/obj/NiSkinInstance.cpp
index 8b8f88578666269a29ddd6adec17d88e2283858c..62a326cf956b9dbe8d37a795088fe12164816503 100644
--- a/obj/NiSkinInstance.cpp
+++ b/obj/NiSkinInstance.cpp
@@ -126,4 +126,4 @@ uint NiSkinInstance::GetBoneCount() const {
 
 Ref<NiNode> NiSkinInstance::GetSkeletonRoot() const {
 	return skeletonRoot;
-}
\ No newline at end of file
+}
diff --git a/obj/NiTriBasedGeom.cpp b/obj/NiTriBasedGeom.cpp
index 6274fc4c9685a920987dd981b548a443d190d789..a5b75d1bc0e11a178a9cac964f23ec780d73859f 100644
--- a/obj/NiTriBasedGeom.cpp
+++ b/obj/NiTriBasedGeom.cpp
@@ -261,6 +261,65 @@ vector<Vector3> NiTriBasedGeom::GetSkinInfluencedVertices() const {
 	return skin_verts;
 }
 
+// Calculate bounding sphere using minimum-volume axis-align bounding box.  Its fast but not a very good fit.
+static void CalcAxisAlignedBox(const vector<SkinWeight> & n, const vector<Vector3>& vertices, Vector3& center, float& radius)
+{
+   //--Calculate center & radius--//
+
+   //Set lows and highs to first vertex
+   Vector3 lows = vertices[ n[0].index ];
+   Vector3 highs = vertices[ n[0].index ];
+
+   //Iterate through the vertices, adjusting the stored values
+   //if a vertex with lower or higher values is found
+   for ( unsigned int i = 0; i < n.size(); ++i ) {
+      const Vector3 & v = vertices[ n[i].index ];
+
+      if ( v.x > highs.x ) highs.x = v.x;
+      else if ( v.x < lows.x ) lows.x = v.x;
+
+      if ( v.y > highs.y ) highs.y = v.y;
+      else if ( v.y < lows.y ) lows.y = v.y;
+
+      if ( v.z > highs.z ) highs.z = v.z;
+      else if ( v.z < lows.z ) lows.z = v.z;
+   }
+
+   //Now we know the extent of the shape, so the center will be the average
+   //of the lows and highs
+   center = (highs + lows) / 2.0f;
+
+   //The radius will be the largest distance from the center
+   Vector3 diff;
+   float dist2(0.0f), maxdist2(0.0f);
+   for ( unsigned int i = 0; i < n.size(); ++i ) {
+      const Vector3 & v = vertices[ n[i].index ];
+
+      diff = center - v;
+      dist2 = diff.x * diff.x + diff.y * diff.y + diff.z * diff.z;
+      if ( dist2 > maxdist2 ) maxdist2 = dist2;
+   };
+   radius = sqrt(maxdist2);
+}
+
+// Calculate bounding sphere using average position of the points.  Better fit but slower.
+static void CalcCenteredSphere(const vector<SkinWeight> & n, const vector<Vector3>& vertices, Vector3& center, float& radius)
+{
+   size_t nv = n.size();
+   Vector3 sum;
+   for (size_t i=0; i<nv; ++i)
+      sum += vertices[ n[i].index ];
+   center = sum / float(nv);
+   radius = 0.0f;
+   for (size_t i=0; i<nv; ++i){
+      Vector3 diff = vertices[ n[i].index ] - center;
+      float mag = diff.Magnitude();
+      radius = max(radius, mag);
+   }
+}
+
+
+
 void NiTriBasedGeom::SetBoneWeights( uint bone_index, const vector<SkinWeight> & n ) {
 	
 	if ( n.size() == 0 ) {
@@ -288,42 +347,9 @@ void NiTriBasedGeom::SetBoneWeights( uint bone_index, const vector<SkinWeight> &
 	//Get vertex array
 	vector<Vector3> vertices = geomData->GetVertices();
 
-	//--Calculate center & radius--//
-	
-	//Set lows and highs to first vertex
-	Vector3 lows = vertices[ n[0].index ];
-	Vector3 highs = vertices[ n[0].index ];
-
-	//Iterate through the vertices, adjusting the stored values
-	//if a vertex with lower or higher values is found
-	for ( unsigned int i = 0; i < n.size(); ++i ) {
-		const Vector3 & v = vertices[ n[i].index ];
-		
-		if ( v.x > highs.x ) highs.x = v.x;
-		else if ( v.x < lows.x ) lows.x = v.x;
-
-		if ( v.y > highs.y ) highs.y = v.y;
-		else if ( v.y < lows.y ) lows.y = v.y;
-
-		if ( v.z > highs.z ) highs.z = v.z;
-		else if ( v.z < lows.z ) lows.z = v.z;
-	}
-
-	//Now we know the extent of the shape, so the center will be the average
-	//of the lows and highs
-	Vector3 center = highs + lows / 2.0f;
-
-	//The radius will be the largest distance from the center
-	Vector3 diff;
-	float dist2(0.0f), maxdist2(0.0f);
-	for ( unsigned int i = 0; i < n.size(); ++i ) {
-		const Vector3 & v = vertices[ n[i].index ];
-
-		diff = center - v;
-		dist2 = diff.x * diff.x + diff.y * diff.y + diff.z * diff.z;
-		if ( dist2 > maxdist2 ) maxdist2 = dist2;
-	};
-	float radius = sqrt(maxdist2);
+   Vector3 center; float radius;
+   //CalcCenteredSphere(n, vertices, center, radius);
+   CalcAxisAlignedBox(n, vertices, center, radius);
 
 	//Translate center by bone matrix
 	center = skinData->GetBoneTransform( bone_index ) * center;