Example #1
0
        public static Dna Load(BulletReader dnaReader, bool swap)
        {
            var dna = new Dna();

            dna.Init(dnaReader, swap);
            return(dna);
        }
Example #2
0
 public static Dna Load(byte[] dnaData, bool swap)
 {
     using (var stream = new MemoryStream(dnaData))
     {
         using (var reader = new BulletReader(stream))
         {
             return Load(reader, swap);
         }
     }
 }
Example #3
0
 public static Dna Load(byte[] dnaData, bool swap)
 {
     using (var stream = new MemoryStream(dnaData))
     {
         using (var reader = new BulletReader(stream))
         {
             return(Load(reader, swap));
         }
     }
 }
Example #4
0
        // Replaces an identifier in serialized data with an actual pointer to something.
        // The handle should be used to free the pointer once it is no longer used.
        private static GCHandle?PinDataAtPointer(byte[] data, int pointerPosition, BulletFile file)
        {
            long pointer = BulletReader.ToPtr(data, pointerPosition);

            if (pointer != 0)
            {
                byte[]   referencedData = file.LibPointers[pointer];
                GCHandle dataHandle     = GCHandle.Alloc(referencedData, GCHandleType.Pinned);
                WritePointer(data, pointerPosition, dataHandle.AddrOfPinnedObject());
                return(dataHandle);
            }
            return(null);
        }
Example #5
0
        private void InitDna()
        {
            _dnaData = IntPtr.Size == 8 ? GetBulletDna64() : GetBulletDna();
            bool swap = !BitConverter.IsLittleEndian;

            using (var stream = new MemoryStream(_dnaData))
            {
                using (var reader = new BulletReader(stream))
                {
                    _dna = Dna.Load(reader, swap);
                }
            }
        }
Example #6
0
        private void LoadDna(FileVerboseMode verboseMode)
        {
            bool swap = (Flags & FileFlags.EndianSwap) != 0;

            using (var stream = new MemoryStream(_fileBuffer, false))
            {
                using (var reader = new BulletReader(stream))
                {
                    long dnaStart = FindDnaChunk(reader);
                    OK = dnaStart != -1;
                    if (!OK)
                    {
                        return;
                    }

                    stream.Position = dnaStart;
                    _fileDna        = Dna.Load(reader, swap);
                }
            }

            if (_fileDna.IsBroken(_version))
            {
                Console.WriteLine("Warning: broken DNA version");
                Flags |= FileFlags.BrokenDna;
            }

            //if ((verboseMode & FileVerboseMode.DumpDnaTypeDefinitions) != 0)
            //    _fileDna.DumpTypeDefinitions();

            byte[] memoryDnaData = IntPtr.Size == 8
                ? Serializer.GetBulletDna64()
                : Serializer.GetBulletDna();
            _memoryDna = Dna.Load(memoryDnaData, !BitConverter.IsLittleEndian);

            _structChanged = _fileDna.Compare(_memoryDna);
        }
Example #7
0
        private void AutoSerializeRootLevelChildren(XmlElement parent)
        {
            foreach (XmlNode node in parent)
            {
                if (node.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                XmlElement element = node as XmlElement;
                switch (element.Name)
                {
                case "btCompoundShapeChildData":
                    DeSerializeCompoundShapeChildData(element);
                    continue;

                case "btCompoundShapeData":
                    DeSerializeCompoundShapeData(element);
                    continue;

                case "btConvexHullShapeData":
                    DeSerializeConvexHullShapeData(element);
                    continue;

                case "btConvexInternalShapeData":
                    DeSerializeConvexInternalShapeData(element);
                    continue;

                case "btDynamicsWorldFloatData":
                    DeSerializeDynamicsWorldData(element);
                    continue;

                case "btGeneric6DofConstraintData":
                    DeSerializeGeneric6DofConstraintData(element);
                    continue;

                case "btRigidBodyFloatData":
                    DeSerializeRigidBodyFloatData(element);
                    continue;

                case "btStaticPlaneShapeData":
                    DeSerializeStaticPlaneShapeData(element);
                    continue;

                case "btVector3FloatData":
                    DeSerializeVector3FloatData(element);
                    continue;

                default:
                    throw new NotImplementedException();
                }
            }

            foreach (byte[] shapeData in _collisionShapeData)
            {
                CollisionShape shape = ConvertCollisionShape(shapeData, _pointerLookup);
                if (shape != null)
                {
                    foreach (KeyValuePair <long, byte[]> lib in _pointerLookup)
                    {
                        if (lib.Value == shapeData)
                        {
                            _shapeMap.Add(lib.Key, shape);
                            break;
                        }
                    }

                    using (var stream = new MemoryStream(shapeData, false))
                    {
                        using (var reader = new BulletReader(stream))
                        {
                            long namePtr = reader.ReadPtr(CollisionShapeData.Offset("Name"));
                            if (namePtr != 0)
                            {
                                byte[] nameData = _pointerLookup[namePtr];
                                int    length   = Array.IndexOf(nameData, (byte)0);
                                string name     = System.Text.Encoding.ASCII.GetString(nameData, 0, length);
                                _objectNameMap.Add(shape, name);
                                _nameShapeMap.Add(name, shape);
                            }
                        }
                    }
                }
            }

            foreach (byte[] rbData in _rigidBodyData)
            {
                ConvertRigidBodyFloat(rbData, _pointerLookup);
            }

            foreach (byte[] constraintData in _constraintData)
            {
                //throw new NotImplementedException();
                //ConvertConstraint(constraintData);
            }
        }
Example #8
0
        public bool ConvertAllObjects(BulletFile file)
        {
            _shapeMap.Clear();
            _bodyMap.Clear();

            foreach (byte[] bvhData in file.Bvhs)
            {
                OptimizedBvh bvh = CreateOptimizedBvh();

                if ((file.Flags & FileFlags.DoublePrecision) != 0)
                {
                    throw new NotImplementedException();
                }
                else
                {
                    // QuantizedBvhData is parsed in C++, so we need to actually fix pointers
                    GCHandle bvhDataHandle    = GCHandle.Alloc(bvhData, GCHandleType.Pinned);
                    IntPtr   bvhDataPinnedPtr = bvhDataHandle.AddrOfPinnedObject();

                    IntPtr contiguousNodesHandlePtr          = IntPtr.Zero;
                    IntPtr quantizedContiguousNodesHandlePtr = IntPtr.Zero;
                    IntPtr subTreeInfoHandlePtr = IntPtr.Zero;

                    using (var stream = new MemoryStream(bvhData))
                    {
                        using (var reader = new BulletReader(stream))
                        {
                            long contiguousNodesPtr          = reader.ReadPtr(QuantizedBvhFloatData.Offset("ContiguousNodesPtr"));
                            long quantizedContiguousNodesPtr = reader.ReadPtr(QuantizedBvhFloatData.Offset("QuantizedContiguousNodesPtr"));
                            long subTreeInfoPtr = reader.ReadPtr(QuantizedBvhFloatData.Offset("SubTreeInfoPtr"));

                            using (var writer = new BulletWriter(stream))
                            {
                                if (contiguousNodesPtr != 0)
                                {
                                    GCHandle contiguousNodesHandle = GCHandle.Alloc(file.LibPointers[contiguousNodesPtr], GCHandleType.Pinned);
                                    contiguousNodesHandlePtr = GCHandle.ToIntPtr(contiguousNodesHandle);
                                    stream.Position          = QuantizedBvhFloatData.Offset("ContiguousNodesPtr");
                                    writer.Write(contiguousNodesHandle.AddrOfPinnedObject());
                                }
                                if (quantizedContiguousNodesPtr != 0)
                                {
                                    GCHandle quantizedContiguousNodesHandle = GCHandle.Alloc(file.LibPointers[quantizedContiguousNodesPtr], GCHandleType.Pinned);
                                    quantizedContiguousNodesHandlePtr = GCHandle.ToIntPtr(quantizedContiguousNodesHandle);
                                    stream.Position = QuantizedBvhFloatData.Offset("QuantizedContiguousNodesPtr");
                                    writer.Write(quantizedContiguousNodesHandle.AddrOfPinnedObject());
                                }
                                if (subTreeInfoPtr != 0)
                                {
                                    GCHandle subTreeInfoHandle = GCHandle.Alloc(file.LibPointers[subTreeInfoPtr], GCHandleType.Pinned);
                                    subTreeInfoHandlePtr = GCHandle.ToIntPtr(subTreeInfoHandle);
                                    stream.Position      = QuantizedBvhFloatData.Offset("SubTreeInfoPtr");
                                    writer.Write(subTreeInfoHandle.AddrOfPinnedObject());
                                }
                            }
                        }
                    }

                    bvh.DeSerializeFloat(bvhDataPinnedPtr);
                    bvhDataHandle.Free();

                    if (contiguousNodesHandlePtr != IntPtr.Zero)
                    {
                        GCHandle.FromIntPtr(contiguousNodesHandlePtr).Free();
                    }
                    if (quantizedContiguousNodesHandlePtr != IntPtr.Zero)
                    {
                        GCHandle.FromIntPtr(quantizedContiguousNodesHandlePtr).Free();
                    }
                    if (subTreeInfoHandlePtr != IntPtr.Zero)
                    {
                        GCHandle.FromIntPtr(subTreeInfoHandlePtr).Free();
                    }
                }

                foreach (KeyValuePair <long, byte[]> lib in file.LibPointers)
                {
                    if (lib.Value == bvhData)
                    {
                        _bvhMap.Add(lib.Key, bvh);
                        break;
                    }
                }
            }

            foreach (byte[] shapeData in file.CollisionShapes)
            {
                CollisionShape shape = ConvertCollisionShape(shapeData, file.LibPointers);
                if (shape != null)
                {
                    foreach (KeyValuePair <long, byte[]> lib in file.LibPointers)
                    {
                        if (lib.Value == shapeData)
                        {
                            _shapeMap.Add(lib.Key, shape);
                            break;
                        }
                    }

                    using (var stream = new MemoryStream(shapeData, false))
                    {
                        using (var reader = new BulletReader(stream))
                        {
                            long namePtr = reader.ReadPtr(CollisionShapeFloatData.Offset("Name"));
                            if (namePtr != 0)
                            {
                                byte[] nameData = file.LibPointers[namePtr];
                                int    length   = Array.IndexOf(nameData, (byte)0);
                                string name     = System.Text.Encoding.ASCII.GetString(nameData, 0, length);
                                _objectNameMap.Add(shape, name);
                                _nameShapeMap.Add(name, shape);
                            }
                        }
                    }
                }
            }

            foreach (byte[] solverInfoData in file.DynamicsWorldInfo)
            {
                if ((file.Flags & FileFlags.DoublePrecision) != 0)
                {
                    //throw new NotImplementedException();
                }
                else
                {
                    //throw new NotImplementedException();
                }
            }

            foreach (byte[] bodyData in file.RigidBodies)
            {
                if ((file.Flags & FileFlags.DoublePrecision) != 0)
                {
                    throw new NotImplementedException();
                }
                else
                {
                    ConvertRigidBodyFloat(bodyData, file.LibPointers);
                }
            }

            foreach (byte[] colObjData in file.CollisionObjects)
            {
                if ((file.Flags & FileFlags.DoublePrecision) != 0)
                {
                    throw new NotImplementedException();
                }
                else
                {
                    using (var colObjStream = new MemoryStream(colObjData, false))
                    {
                        using (var colObjReader = new BulletReader(colObjStream))
                        {
                            long           shapePtr       = colObjReader.ReadPtr(CollisionObjectFloatData.Offset("CollisionShape"));
                            CollisionShape shape          = _shapeMap[shapePtr];
                            Math.Matrix    startTransform = colObjReader.ReadMatrix(CollisionObjectFloatData.Offset("WorldTransform"));
                            long           namePtr        = colObjReader.ReadPtr(CollisionObjectFloatData.Offset("Name"));
                            string         name           = null;
                            if (namePtr != 0)
                            {
                                byte[] nameData = file.FindLibPointer(namePtr);
                                int    length   = Array.IndexOf(nameData, (byte)0);
                                name = System.Text.Encoding.ASCII.GetString(nameData, 0, length);
                            }
                            CollisionObject colObj = CreateCollisionObject(ref startTransform, shape, name);
                            _bodyMap.Add(colObjData, colObj);
                        }
                    }
                }
            }

            foreach (byte[] constraintData in file.Constraints)
            {
                var stream = new MemoryStream(constraintData, false);
                using (var reader = new BulletReader(stream))
                {
                    long collisionObjectAPtr = reader.ReadPtr(TypedConstraintFloatData.Offset("RigidBodyA"));
                    long collisionObjectBPtr = reader.ReadPtr(TypedConstraintFloatData.Offset("RigidBodyB"));

                    RigidBody a = null, b = null;

                    if (collisionObjectAPtr != 0)
                    {
                        if (!file.LibPointers.ContainsKey(collisionObjectAPtr))
                        {
                            a = TypedConstraint.GetFixedBody();
                        }
                        else
                        {
                            byte[] coData = file.LibPointers[collisionObjectAPtr];
                            a = RigidBody.Upcast(_bodyMap[coData]);
                            if (a == null)
                            {
                                a = TypedConstraint.GetFixedBody();
                            }
                        }
                    }

                    if (collisionObjectBPtr != 0)
                    {
                        if (!file.LibPointers.ContainsKey(collisionObjectBPtr))
                        {
                            b = TypedConstraint.GetFixedBody();
                        }
                        else
                        {
                            byte[] coData = file.LibPointers[collisionObjectBPtr];
                            b = RigidBody.Upcast(_bodyMap[coData]);
                            if (b == null)
                            {
                                b = TypedConstraint.GetFixedBody();
                            }
                        }
                    }

                    if (a == null && b == null)
                    {
                        stream.Dispose();
                        continue;
                    }

                    if ((file.Flags & FileFlags.DoublePrecision) != 0)
                    {
                        throw new NotImplementedException();
                    }
                    else
                    {
                        ConvertConstraintFloat(a, b, constraintData, file.Version, file.LibPointers);
                    }
                }
                stream.Dispose();
            }

            return(true);
        }
        public bool ConvertAllObjects(BulletFile file)
        {
            _shapeMap.Clear();
            _bodyMap.Clear();

            foreach (byte[] bvhData in file._bvhs)
            {
                OptimizedBvh bvh = CreateOptimizedBvh();

                if ((file.Flags & FileFlags.DoublePrecision) != 0)
                {
                    throw new NotImplementedException();
                }
                else
                {
                    // QuantizedBvhData is parsed in C++, so we need to actually fix pointers
                    GCHandle bvhDataHandle = GCHandle.Alloc(bvhData, GCHandleType.Pinned);
                    IntPtr bvhDataPinnedPtr = bvhDataHandle.AddrOfPinnedObject();

                    IntPtr contiguousNodesHandlePtr = IntPtr.Zero;
                    IntPtr quantizedContiguousNodesHandlePtr = IntPtr.Zero;
                    IntPtr subTreeInfoHandlePtr = IntPtr.Zero;

                    using (MemoryStream stream = new MemoryStream(bvhData))
                    {
                        using (BulletReader reader = new BulletReader(stream))
                        {
                            long contiguousNodesPtr = reader.ReadPtr(QuantizedBvhFloatData.Offset("ContiguousNodesPtr"));
                            long quantizedContiguousNodesPtr = reader.ReadPtr(QuantizedBvhFloatData.Offset("QuantizedContiguousNodesPtr"));
                            long subTreeInfoPtr = reader.ReadPtr(QuantizedBvhFloatData.Offset("SubTreeInfoPtr"));

                            using (BulletWriter writer = new BulletWriter(stream))
                            {
                                if (contiguousNodesPtr != 0)
                                {
                                    GCHandle contiguousNodesHandle = GCHandle.Alloc(file.LibPointers[contiguousNodesPtr], GCHandleType.Pinned);
                                    contiguousNodesHandlePtr = GCHandle.ToIntPtr(contiguousNodesHandle);
                                    stream.Position = QuantizedBvhFloatData.Offset("ContiguousNodesPtr");
                                    writer.Write(contiguousNodesHandle.AddrOfPinnedObject());
                                }
                                if (quantizedContiguousNodesPtr != 0)
                                {
                                    GCHandle quantizedContiguousNodesHandle = GCHandle.Alloc(file.LibPointers[quantizedContiguousNodesPtr], GCHandleType.Pinned);
                                    quantizedContiguousNodesHandlePtr = GCHandle.ToIntPtr(quantizedContiguousNodesHandle);
                                    stream.Position = QuantizedBvhFloatData.Offset("QuantizedContiguousNodesPtr");
                                    writer.Write(quantizedContiguousNodesHandle.AddrOfPinnedObject());
                                }
                                if (subTreeInfoPtr != 0)
                                {
                                    GCHandle subTreeInfoHandle = GCHandle.Alloc(file.LibPointers[subTreeInfoPtr], GCHandleType.Pinned);
                                    subTreeInfoHandlePtr = GCHandle.ToIntPtr(subTreeInfoHandle);
                                    stream.Position = QuantizedBvhFloatData.Offset("SubTreeInfoPtr");
                                    writer.Write(subTreeInfoHandle.AddrOfPinnedObject());
                                }
                            }
                        }
                    }

                    bvh.DeSerializeFloat(bvhDataPinnedPtr);
                    bvhDataHandle.Free();

                    if (contiguousNodesHandlePtr != IntPtr.Zero)
                    {
                        GCHandle.FromIntPtr(contiguousNodesHandlePtr).Free();
                    }
                    if (quantizedContiguousNodesHandlePtr != IntPtr.Zero)
                    {
                        GCHandle.FromIntPtr(quantizedContiguousNodesHandlePtr).Free();
                    }
                    if (subTreeInfoHandlePtr != IntPtr.Zero)
                    {
                        GCHandle.FromIntPtr(subTreeInfoHandlePtr).Free();
                    }
                }

                foreach (KeyValuePair<long, byte[]> lib in file.LibPointers)
                {
                    if (lib.Value == bvhData)
                    {
                        _bvhMap.Add(lib.Key, bvh);
                        break;
                    }
                }
            }

            foreach (byte[] shapeData in file._collisionShapes)
            {
                CollisionShape shape = ConvertCollisionShape(shapeData, file.LibPointers);
                if (shape != null)
                {
                    foreach (KeyValuePair<long, byte[]> lib in file.LibPointers)
                    {
                        if (lib.Value == shapeData)
                        {
                            _shapeMap.Add(lib.Key, shape);
                            break;
                        }
                    }

                    using (MemoryStream stream = new MemoryStream(shapeData, false))
                    {
                        using (BulletReader reader = new BulletReader(stream))
                        {
                            long namePtr = reader.ReadPtr(CollisionShapeFloatData.Offset("Name"));
                            if (namePtr != 0)
                            {
                                byte[] nameData = file.LibPointers[namePtr];
                                int length = Array.IndexOf(nameData, (byte)0);
                                string name = System.Text.Encoding.ASCII.GetString(nameData, 0, length);
                                _objectNameMap.Add(shape, name);
                                _nameShapeMap.Add(name, shape);
                            }
                        }
                    }
                }
            }

            foreach (byte[] solverInfoData in file._dynamicsWorldInfo)
            {
                if ((file.Flags & FileFlags.DoublePrecision) != 0)
                {
                    //throw new NotImplementedException();
                }
                else
                {
                    //throw new NotImplementedException();
                }
            }

            foreach (byte[] bodyData in file._rigidBodies)
            {
                if ((file.Flags & FileFlags.DoublePrecision) != 0)
                {
                    throw new NotImplementedException();
                }
                else
                {
                    ConvertRigidBodyFloat(bodyData, file.LibPointers);
                }
            }

            foreach (byte[] colObjData in file._collisionObjects)
            {
                if ((file.Flags & FileFlags.DoublePrecision) != 0)
                {
                    throw new NotImplementedException();
                }
                else
                {
                    using (MemoryStream colObjStream = new MemoryStream(colObjData, false))
                    {
                        using (BulletReader colObjReader = new BulletReader(colObjStream))
                        {
                            long shapePtr = colObjReader.ReadPtr(CollisionObjectFloatData.Offset("CollisionShape"));
                            CollisionShape shape = _shapeMap[shapePtr];
                            Math.Matrix startTransform = colObjReader.ReadMatrix(CollisionObjectFloatData.Offset("WorldTransform"));
                            long namePtr = colObjReader.ReadPtr(CollisionObjectFloatData.Offset("Name"));
                            string name = null;
                            if (namePtr != 0)
                            {
                                byte[] nameData = file.FindLibPointer(namePtr);
                                int length = Array.IndexOf(nameData, (byte)0);
                                name = System.Text.Encoding.ASCII.GetString(nameData, 0, length);
                            }
                            CollisionObject colObj = CreateCollisionObject(ref startTransform, shape, name);
                            _bodyMap.Add(colObjData, colObj);
                        }
                    }
                }
            }

            foreach (byte[] constraintData in file._constraints)
            {
                MemoryStream stream = new MemoryStream(constraintData, false);
                using (BulletReader reader = new BulletReader(stream))
                {
                    long collisionObjectAPtr = reader.ReadPtr(TypedConstraintFloatData.Offset("RigidBodyA"));
                    long collisionObjectBPtr = reader.ReadPtr(TypedConstraintFloatData.Offset("RigidBodyB"));

                    RigidBody a = null, b = null;

                    if (collisionObjectAPtr != 0)
                    {
                        if (!file.LibPointers.ContainsKey(collisionObjectAPtr))
                        {
                            a = TypedConstraint.GetFixedBody();
                        }
                        else
                        {
                            byte[] coData = file.LibPointers[collisionObjectAPtr];
                            a = RigidBody.Upcast(_bodyMap[coData]);
                            if (a == null)
                            {
                                a = TypedConstraint.GetFixedBody();
                            }
                        }
                    }

                    if (collisionObjectBPtr != 0)
                    {
                        if (!file.LibPointers.ContainsKey(collisionObjectBPtr))
                        {
                            b = TypedConstraint.GetFixedBody();
                        }
                        else
                        {
                            byte[] coData = file.LibPointers[collisionObjectBPtr];
                            b = RigidBody.Upcast(_bodyMap[coData]);
                            if (b == null)
                            {
                                b = TypedConstraint.GetFixedBody();
                            }
                        }
                    }

                    if (a == null && b == null)
                    {
                        stream.Dispose();
                        continue;
                    }

                    if ((file.Flags & FileFlags.DoublePrecision) != 0)
                    {
                        throw new NotImplementedException();
                    }
                    else
                    {
                        ConvertConstraintFloat(a, b, constraintData, file.Version, file.LibPointers);
                    }
                }
                stream.Dispose();
            }

            return true;
        }
        protected void ConvertConstraintFloat(RigidBody rigidBodyA, RigidBody rigidBodyB, byte[] constraintData, int fileVersion, Dictionary<long, byte[]> libPointers)
        {
            TypedConstraint constraint = null;
            MemoryStream stream = new MemoryStream(constraintData, false);
            BulletReader reader = new BulletReader(stream);

            TypedConstraintType type = (TypedConstraintType)reader.ReadInt32(TypedConstraintFloatData.Offset("ObjectType"));
            switch (type)
            {
                case TypedConstraintType.Point2Point:
                    {
                        Vector3 pivotInA = reader.ReadVector3(Point2PointConstraintFloatData.Offset("PivotInA"));
                        if (rigidBodyA != null && rigidBodyB != null)
                        {
                            Vector3 pivotInB = reader.ReadVector3(Point2PointConstraintFloatData.Offset("PivotInB"));
                            constraint = CreatePoint2PointConstraint(rigidBodyA, rigidBodyB, ref pivotInA, ref pivotInB);
                        }
                        else
                        {
                            constraint = CreatePoint2PointConstraint(rigidBodyA, ref pivotInA);
                        }
                        break;
                    }
                case TypedConstraintType.ConeTwist:
                    {
                        ConeTwistConstraint coneTwist;
                        Matrix rbaFrame = reader.ReadMatrix(ConeTwistConstraintFloatData.Offset("RigidBodyAFrame"));
                        if (rigidBodyA != null && rigidBodyB != null)
                        {
                            Matrix rbbFrame = reader.ReadMatrix(ConeTwistConstraintFloatData.Offset("RigidBodyBFrame"));
                            coneTwist = CreateConeTwistConstraint(rigidBodyA, rigidBodyB, ref rbaFrame, ref rbbFrame);
                        }
                        else
                        {
                            coneTwist = CreateConeTwistConstraint(rigidBodyA, ref rbaFrame);
                        }
                        coneTwist.SetLimit(
                            reader.ReadSingle(ConeTwistConstraintFloatData.Offset("SwingSpan1")),
                            reader.ReadSingle(ConeTwistConstraintFloatData.Offset("SwingSpan2")),
                            reader.ReadSingle(ConeTwistConstraintFloatData.Offset("TwistSpan")),
                            reader.ReadSingle(ConeTwistConstraintFloatData.Offset("LimitSoftness")),
                            reader.ReadSingle(ConeTwistConstraintFloatData.Offset("BiasFactor")),
                            reader.ReadSingle(ConeTwistConstraintFloatData.Offset("RelaxationFactor")));
                        coneTwist.Damping = reader.ReadSingle(ConeTwistConstraintFloatData.Offset("Damping"));

                        constraint = coneTwist;
                        break;
                    }
                case TypedConstraintType.D6:
                    {
                        Generic6DofConstraint dof = null;
                        if (rigidBodyA != null && rigidBodyB != null)
                        {
                            Matrix rbaFrame = reader.ReadMatrix(Generic6DofConstraintFloatData.Offset("RigidBodyAFrame"));
                            Matrix rbbFrame = reader.ReadMatrix(Generic6DofConstraintFloatData.Offset("RigidBodyBFrame"));
                            int useLinearReferenceFrameA = reader.ReadInt32(Generic6DofConstraintFloatData.Offset("UseLinearReferenceFrameA"));
                            dof = CreateGeneric6DofConstraint(rigidBodyA, rigidBodyB, ref rbaFrame, ref rbbFrame, useLinearReferenceFrameA != 0);
                        }
                        else
                        {
                            if (rigidBodyB != null)
                            {
                                Matrix rbbFrame = reader.ReadMatrix(Generic6DofConstraintFloatData.Offset("RigidBodyBFrame"));
                                int useLinearReferenceFrameA = reader.ReadInt32(Generic6DofConstraintFloatData.Offset("UseLinearReferenceFrameA"));
                                dof = CreateGeneric6DofConstraint(rigidBodyB, ref rbbFrame, useLinearReferenceFrameA != 0);
                            }
                            else
                            {
                                Console.WriteLine("Error in WorldImporter.CreateGeneric6DofConstraint: missing rigidBodyB");
                            }
                        }

                        if (dof != null)
                        {
                            dof.AngularLowerLimit = reader.ReadVector3(Generic6DofConstraintFloatData.Offset("AngularLowerLimit"));
                            dof.AngularUpperLimit = reader.ReadVector3(Generic6DofConstraintFloatData.Offset("AngularUpperLimit"));
                            dof.LinearLowerLimit = reader.ReadVector3(Generic6DofConstraintFloatData.Offset("LinearLowerLimit"));
                            dof.LinearUpperLimit = reader.ReadVector3(Generic6DofConstraintFloatData.Offset("LinearUpperLimit"));
                        }
                        constraint = dof;
                        break;
                    }
                case TypedConstraintType.D6Spring:
                    {
                        Generic6DofSpringConstraint dof = null;
                        int sixDofData = Generic6DofSpringConstraintFloatData.Offset("SixDofData");
                        if (rigidBodyA != null && rigidBodyB != null)
                        {
                            Matrix rbaFrame = reader.ReadMatrix(sixDofData + Generic6DofConstraintFloatData.Offset("RigidBodyAFrame"));
                            Matrix rbbFrame = reader.ReadMatrix(sixDofData + Generic6DofConstraintFloatData.Offset("RigidBodyBFrame"));
                            int useLinearReferenceFrameA = reader.ReadInt32(sixDofData + Generic6DofConstraintFloatData.Offset("UseLinearReferenceFrameA"));
                            dof = CreateGeneric6DofSpringConstraint(rigidBodyA, rigidBodyB, ref rbaFrame, ref rbbFrame, useLinearReferenceFrameA != 0);
                        }
                        else
                        {
                            Console.WriteLine("Error in WorldImporter.CreateGeneric6DofSpringConstraint: requires rigidBodyA && rigidBodyB");
                        }

                        if (dof != null)
                        {
                            dof.AngularLowerLimit = reader.ReadVector3(sixDofData + Generic6DofConstraintFloatData.Offset("AngularLowerLimit"));
                            dof.AngularUpperLimit = reader.ReadVector3(sixDofData + Generic6DofConstraintFloatData.Offset("AngularUpperLimit"));
                            dof.LinearLowerLimit = reader.ReadVector3(sixDofData + Generic6DofConstraintFloatData.Offset("LinearLowerLimit"));
                            dof.LinearUpperLimit = reader.ReadVector3(sixDofData + Generic6DofConstraintFloatData.Offset("LinearUpperLimit"));

                            int i;
                            if (fileVersion > 280)
                            {
                                int springEnabledOffset = Generic6DofSpringConstraintFloatData.Offset("SpringEnabled");
                                int equilibriumPointOffset = Generic6DofSpringConstraintFloatData.Offset("EquilibriumPoint");
                                int springStiffnessOffset = Generic6DofSpringConstraintFloatData.Offset("SpringStiffness");
                                int springDampingOffset = Generic6DofSpringConstraintFloatData.Offset("SpringDamping");
                                for (i = 0; i < 6; i++)
                                {
                                    dof.SetStiffness(i, reader.ReadSingle(springStiffnessOffset + sizeof(float) * i));
                                    dof.SetEquilibriumPoint(i, reader.ReadSingle(equilibriumPointOffset + sizeof(float) * i));
                                    dof.EnableSpring(i, reader.ReadInt32(springEnabledOffset + sizeof(int) * i) != 0);
                                    dof.SetDamping(i, reader.ReadSingle(springDampingOffset + sizeof(float) * i));
                                }
                            }
                        }
                        constraint = dof;
                        break;
                    }
                case TypedConstraintType.D6Spring2:
                    {
                        Generic6DofSpring2Constraint dof = null;
                        if (rigidBodyA != null && rigidBodyB != null)
                        {
                            Matrix rbaFrame = reader.ReadMatrix(Generic6DofSpring2ConstraintFloatData.Offset("RigidBodyAFrame"));
                            Matrix rbbFrame = reader.ReadMatrix(Generic6DofSpring2ConstraintFloatData.Offset("RigidBodyBFrame"));
                            RotateOrder rotateOrder = (RotateOrder)reader.ReadInt32(Generic6DofSpring2ConstraintFloatData.Offset("RotateOrder"));
                            dof = CreateGeneric6DofSpring2Constraint(rigidBodyA, rigidBodyB, ref rbaFrame, ref rbbFrame, rotateOrder);
                        }
                        else
                        {
                            Console.WriteLine("Error in WorldImporter.CreateGeneric6DofSpring2Constraint: requires rigidBodyA && rigidBodyB");
                        }

                        if (dof != null)
                        {
                            dof.AngularLowerLimit = reader.ReadVector3(Generic6DofSpring2ConstraintFloatData.Offset("AngularLowerLimit"));
                            dof.AngularUpperLimit = reader.ReadVector3(Generic6DofSpring2ConstraintFloatData.Offset("AngularUpperLimit"));
                            dof.LinearLowerLimit = reader.ReadVector3(Generic6DofSpring2ConstraintFloatData.Offset("LinearLowerLimit"));
                            dof.LinearUpperLimit = reader.ReadVector3(Generic6DofSpring2ConstraintFloatData.Offset("LinearUpperLimit"));

                            int i;
                            if (fileVersion > 280)
                            {
                                int linearSpringStiffnessOffset = Generic6DofSpring2ConstraintFloatData.Offset("LinearSpringStiffness");
                                int linearSpringStiffnessLimitedOffset = Generic6DofSpring2ConstraintFloatData.Offset("LinearSpringStiffnessLimited");
                                int linearEnableSpringdOffset = Generic6DofSpring2ConstraintFloatData.Offset("LinearEnableSpring");
                                int linearEquilibriumPointOffset = Generic6DofSpring2ConstraintFloatData.Offset("LinearEquilibriumPoint");
                                int linearSpringDampingOffset = Generic6DofSpring2ConstraintFloatData.Offset("LinearSpringDamping");
                                int linearSpringDampingLimitedOffset = Generic6DofSpring2ConstraintFloatData.Offset("LinearSpringDampingLimited");
                                for (i = 0; i < 3; i++)
                                {
                                    dof.SetStiffness(i, reader.ReadSingle(linearSpringStiffnessOffset + sizeof(float) * i), reader.ReadByte(linearSpringStiffnessLimitedOffset + sizeof(byte) * i) != 0);
                                    dof.SetEquilibriumPoint(i, reader.ReadSingle(linearEquilibriumPointOffset + sizeof(float) * i));
                                    dof.EnableSpring(i, reader.ReadInt32(linearEnableSpringdOffset + sizeof(byte) * i) != 0);
                                    dof.SetDamping(i, reader.ReadSingle(linearSpringDampingOffset + sizeof(float) * i), reader.ReadByte(linearSpringDampingLimitedOffset + sizeof(float) * i) != 0);
                                }

                                int angularSpringStiffnessOffset = Generic6DofSpring2ConstraintFloatData.Offset("AngularSpringStiffness");
                                int angularSpringStiffnessLimitedOffset = Generic6DofSpring2ConstraintFloatData.Offset("AngularSpringStiffnessLimited");
                                int angularEnableSpringdOffset = Generic6DofSpring2ConstraintFloatData.Offset("AngularEnableSpring");
                                int angularEquilibriumPointOffset = Generic6DofSpring2ConstraintFloatData.Offset("AngularEquilibriumPoint");
                                int angularSpringDampingOffset = Generic6DofSpring2ConstraintFloatData.Offset("AngularSpringDamping");
                                int angularSpringDampingLimitedOffset = Generic6DofSpring2ConstraintFloatData.Offset("AngularSpringDampingLimited");
                                for (i = 0; i < 3; i++)
                                {
                                    dof.SetStiffness(i + 3, reader.ReadSingle(angularSpringStiffnessOffset + sizeof(float) * i), reader.ReadByte(angularSpringStiffnessLimitedOffset + sizeof(byte) * i) != 0);
                                    dof.SetEquilibriumPoint(i + 3, reader.ReadSingle(angularEquilibriumPointOffset + sizeof(float) * i));
                                    dof.EnableSpring(i + 3, reader.ReadInt32(angularEnableSpringdOffset + sizeof(byte) * i) != 0);
                                    dof.SetDamping(i + 3, reader.ReadSingle(angularSpringDampingOffset + sizeof(float) * i), reader.ReadByte(angularSpringDampingLimitedOffset + sizeof(float) * i) != 0);
                                }
                            }
                        }
                        constraint = dof;
                        break;
                    }
                case TypedConstraintType.Gear:
                    {
                        GearConstraint gear;
                        if (rigidBodyA != null && rigidBodyB != null)
                        {
                            Vector3 axisInA = reader.ReadVector3(GearConstraintFloatData.Offset("AxisInA"));
                            Vector3 axisInB = reader.ReadVector3(GearConstraintFloatData.Offset("AxisInB"));
                            float ratio = reader.ReadSingle(GearConstraintFloatData.Offset("Ratio"));
                            gear = CreateGearConstraint(rigidBodyA, rigidBodyB, ref axisInA, ref axisInB, ratio);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        constraint = gear;
                        break;
                    }
                case TypedConstraintType.Hinge:
                    {
                        HingeConstraint hinge;
                        Matrix rbaFrame = reader.ReadMatrix(HingeConstraintFloatData.Offset("RigidBodyAFrame"));
                        int useReferenceFrameA = reader.ReadInt32(HingeConstraintFloatData.Offset("UseReferenceFrameA"));
                        if (rigidBodyA != null && rigidBodyB != null)
                        {
                            Matrix rbbFrame = reader.ReadMatrix(HingeConstraintFloatData.Offset("RigidBodyBFrame"));
                            hinge = CreateHingeConstraint(rigidBodyA, rigidBodyB, ref rbaFrame, ref rbbFrame, useReferenceFrameA != 0);
                        }
                        else
                        {
                            hinge = CreateHingeConstraint(rigidBodyA, ref rbaFrame, useReferenceFrameA != 0);
                        }
                        if (reader.ReadInt32(HingeConstraintFloatData.Offset("EnableAngularMotor")) != 0)
                        {
                            hinge.EnableAngularMotor(true,
                                reader.ReadSingle(HingeConstraintFloatData.Offset("MotorTargetVelocity")),
                                reader.ReadSingle(HingeConstraintFloatData.Offset("MaxMotorImpulse")));
                        }
                        hinge.AngularOnly = reader.ReadInt32(HingeConstraintFloatData.Offset("AngularOnly")) != 0;
                        hinge.SetLimit(
                            reader.ReadSingle(HingeConstraintFloatData.Offset("LowerLimit")),
                            reader.ReadSingle(HingeConstraintFloatData.Offset("UpperLimit")),
                            reader.ReadSingle(HingeConstraintFloatData.Offset("LimitSoftness")),
                            reader.ReadSingle(HingeConstraintFloatData.Offset("BiasFactor")),
                            reader.ReadSingle(HingeConstraintFloatData.Offset("RelaxationFactor")));
                        constraint = hinge;
                        break;
                    }
                case TypedConstraintType.Slider:
                    {
                        SliderConstraint slider;
                        Matrix rbbFrame = reader.ReadMatrix(SliderConstraintFloatData.Offset("RigidBodyBFrame"));
                        int useLinearReferenceFrameA = reader.ReadInt32(SliderConstraintFloatData.Offset("UseLinearReferenceFrameA"));
                        if (rigidBodyA != null && rigidBodyB != null)
                        {
                            Matrix rbaFrame = reader.ReadMatrix(SliderConstraintFloatData.Offset("RigidBodyAFrame"));
                            slider = CreateSliderConstraint(rigidBodyA, rigidBodyB, ref rbaFrame, ref rbbFrame, useLinearReferenceFrameA != 0);
                        }
                        else
                        {
                            slider = CreateSliderConstraint(rigidBodyB, ref rbbFrame, useLinearReferenceFrameA != 0);
                        }
                        slider.LowerLinearLimit = reader.ReadSingle(SliderConstraintFloatData.Offset("LinearLowerLimit"));
                        slider.UpperLinearLimit = reader.ReadSingle(SliderConstraintFloatData.Offset("LinearUpperLimit"));
                        slider.LowerAngularLimit = reader.ReadSingle(SliderConstraintFloatData.Offset("AngularLowerLimit"));
                        slider.UpperAngularLimit = reader.ReadSingle(SliderConstraintFloatData.Offset("AngularUpperLimit"));
                        slider.UseFrameOffset = reader.ReadInt32(SliderConstraintFloatData.Offset("UseOffsetForConstraintFrame")) != 0;
                        break;
                    }
                default:
                    throw new NotImplementedException();
            }

            if (constraint != null)
            {
                constraint.DebugDrawSize = reader.ReadSingle(TypedConstraintFloatData.Offset("DebugDrawSize"));
                // those fields didn't exist and set to zero for pre-280 versions, so do a check here
                if (fileVersion >= 280)
                {
                    constraint.BreakingImpulseThreshold = reader.ReadSingle(TypedConstraintFloatData.Offset("BreakingImpulseThreshold"));
                    constraint.IsEnabled = reader.ReadInt32(TypedConstraintFloatData.Offset("IsEnabled")) != 0;
                    constraint.OverrideNumSolverIterations = reader.ReadInt32(TypedConstraintFloatData.Offset("OverrideNumSolverIterations"));
                }

                long namePtr = reader.ReadPtr(TypedConstraintFloatData.Offset("Name"));
                if (namePtr != 0)
                {
                    byte[] nameData = libPointers[namePtr];
                    int length = Array.IndexOf(nameData, (byte)0);
                    string name = System.Text.Encoding.ASCII.GetString(nameData, 0, length);
                    _nameConstraintMap.Add(name, constraint);
                    _objectNameMap.Add(constraint, name);
                }

                if (_dynamicsWorld != null)
                {
                    _dynamicsWorld.AddConstraint(constraint);
                }
            }

            reader.Dispose();
            stream.Dispose();
        }
        protected CollisionShape ConvertCollisionShape(byte[] shapeData, Dictionary<long, byte[]> libPointers)
        {
            CollisionShape shape = null;
            MemoryStream stream = new MemoryStream(shapeData, false);
            BulletReader reader = new BulletReader(stream);

            BroadphaseNativeType type = (BroadphaseNativeType) reader.ReadInt32(CollisionShapeFloatData.Offset("ShapeType"));
            stream.Position = Marshal.SizeOf(typeof(CollisionShapeFloatData));
            switch (type)
            {
                case BroadphaseNativeType.StaticPlaneShape:
                    {
                        Vector3 localScaling = reader.ReadVector3();
                        Vector3 planeNormal = reader.ReadVector3();
                        float planeConstant = reader.ReadSingle();
                        shape = CreatePlaneShape(ref planeNormal, planeConstant);
                        shape.LocalScaling = localScaling;
                        break;
                    }
                case BroadphaseNativeType.GImpactShape:
                    {
                        //StridingMeshInterfaceData* interfaceData = CreateStridingMeshInterfaceData(&gimpactData->m_meshInterface)
                        TriangleIndexVertexArray meshInterface = CreateMeshInterface(shapeData, GImpactMeshShapeData.Offset("MeshInterface"), libPointers);

                        GImpactShapeType gImpactType = (GImpactShapeType)reader.ReadInt32(GImpactMeshShapeData.Offset("GImpactSubType"));
                        if (gImpactType == GImpactShapeType.TrimeshShape)
                        {
                            GImpactMeshShape gimpactShape = CreateGimpactShape(meshInterface);
                            gimpactShape.LocalScaling = reader.ReadVector3(GImpactMeshShapeData.Offset("LocalScaling"));
                            gimpactShape.Margin = reader.ReadSingle(GImpactMeshShapeData.Offset("CollisionMargin"));
                            gimpactShape.UpdateBound();
                            shape = gimpactShape;
                        }
                        else
                        {
            #if DEBUG
                            Console.WriteLine("Unsupported GImpact subtype");
            #endif
                        }
                        break;
                    }
                case BroadphaseNativeType.CompoundShape:
                    {
                        long childShapesPtr = reader.ReadPtr();
                        byte[] childShapes = libPointers[childShapesPtr];
                        int numChildShapes = reader.ReadInt32();
                        //float collisionMargin = reader.ReadInt32();
                        CompoundShape compoundShape = CreateCompoundShape();
                        using (MemoryStream shapeStream = new MemoryStream(childShapes, false))
                        {
                            using (BulletReader shapeReader = new BulletReader(shapeStream))
                            {
                                for (int i = 0; i < numChildShapes; i++)
                                {
                                    Matrix localTransform = shapeReader.ReadMatrix();
                                    long childShapePtr = shapeReader.ReadPtr();
                                    int childShapeType = shapeReader.ReadInt32();
                                    float childMargin = shapeReader.ReadSingle();
                                    CollisionShape childShape = ConvertCollisionShape(libPointers[childShapePtr], libPointers);
                                    compoundShape.AddChildShape(localTransform, childShape);
                                }
                            }
                        }
                        shape = compoundShape;
                        break;
                    }
                case BroadphaseNativeType.BoxShape:
                case BroadphaseNativeType.CapsuleShape:
                case BroadphaseNativeType.ConeShape:
                case BroadphaseNativeType.ConvexHullShape:
                case BroadphaseNativeType.CylinderShape:
                case BroadphaseNativeType.MultiSphereShape:
                case BroadphaseNativeType.SphereShape:
                    {
                        Vector3 localScaling = reader.ReadVector3();
                        Vector3 implicitShapeDimensions = reader.ReadVector3();
                        float collisionMargin = reader.ReadSingle();
                        stream.Position += 4; // m_padding
                        switch (type)
                        {
                            case BroadphaseNativeType.BoxShape:
                                {
                                    Vector3 boxExtents = implicitShapeDimensions / localScaling + new Vector3(collisionMargin);
                                    BoxShape box = CreateBoxShape(ref boxExtents) as BoxShape;
                                    //box.InitializePolyhedralFeatures();
                                    shape = box;
                                    break;
                                }
                            case BroadphaseNativeType.CapsuleShape:
                                {
                                    Vector3 halfExtents = implicitShapeDimensions + new Vector3(collisionMargin);
                                    int upAxis = reader.ReadInt32();
                                    switch (upAxis)
                                    {
                                        case 0:
                                            shape = CreateCapsuleShapeX(halfExtents.Y, halfExtents.X);
                                            break;
                                        case 1:
                                            shape = CreateCapsuleShapeY(halfExtents.X, halfExtents.Y);
                                            break;
                                        case 2:
                                            shape = CreateCapsuleShapeZ(halfExtents.X, halfExtents.Z);
                                            break;
                                        default:
                                            Console.WriteLine("error: wrong up axis for btCapsuleShape");
                                            break;
                                    }
                                    break;
                                }
                            case BroadphaseNativeType.ConeShape:
                                {
                                    Vector3 halfExtents = implicitShapeDimensions; // + new Vector3(collisionMargin);
                                    int upAxis = reader.ReadInt32();
                                    switch (upAxis)
                                    {
                                        case 0:
                                            shape = CreateConeShapeX(halfExtents.Y, halfExtents.X);
                                            break;
                                        case 1:
                                            shape = CreateConeShapeY(halfExtents.X, halfExtents.Y);
                                            break;
                                        case 2:
                                            shape = CreateConeShapeZ(halfExtents.X, halfExtents.Z);
                                            break;
                                        default:
                                            Console.WriteLine("unknown Cone up axis");
                                            break;
                                    }
                                    break;
                                }
                            case BroadphaseNativeType.ConvexHullShape:
                                {
                                    long unscaledPointsFloatPtr = reader.ReadPtr();
                                    long unscaledPointsDoublePtr = reader.ReadPtr();
                                    int numPoints = reader.ReadInt32();

                                    byte[] points = libPointers[unscaledPointsFloatPtr];
                                    ConvexHullShape hullShape = CreateConvexHullShape();
                                    using (MemoryStream pointStream = new MemoryStream(points, false))
                                    {
                                        using (BulletReader pointReader = new BulletReader(pointStream))
                                        {
                                            for (int i = 0; i < numPoints; i++)
                                            {
                                                hullShape.AddPoint(pointReader.ReadVector3());
                                            }
                                        }
                                    }
                                    hullShape.Margin = collisionMargin;
                                    //hullShape.InitializePolyhedralFeatures();
                                    shape = hullShape;
                                    break;
                                }
                            case BroadphaseNativeType.CylinderShape:
                                {
                                    Vector3 halfExtents = implicitShapeDimensions + new Vector3(collisionMargin);
                                    int upAxis = reader.ReadInt32();
                                    switch (upAxis)
                                    {
                                        case 0:
                                            shape = CreateCylinderShapeX(halfExtents.Y, halfExtents.X);
                                            break;
                                        case 1:
                                            shape = CreateCylinderShapeY(halfExtents.X, halfExtents.Y);
                                            break;
                                        case 2:
                                            shape = CreateCylinderShapeZ(halfExtents.X, halfExtents.Z);
                                            break;
                                        default:
                                            Console.WriteLine("unknown Cylinder up axis");
                                            break;
                                    }
                                    break;
                                }
                            case BroadphaseNativeType.MultiSphereShape:
                                {
                                    long localPositionArrayPtr = reader.ReadPtr();
                                    byte[] localPositionArray = libPointers[localPositionArrayPtr];
                                    int localPositionArraySize = reader.ReadInt32();
                                    Vector3[] positions = new Vector3[localPositionArraySize];
                                    float[] radi = new float[localPositionArraySize];
                                    using (MemoryStream localPositionArrayStream = new MemoryStream(localPositionArray, false))
                                    {
                                        using (BulletReader localPositionArrayReader = new BulletReader(localPositionArrayStream))
                                        {
                                            for (int i = 0; i < localPositionArraySize; i++)
                                            {
                                                positions[i] = localPositionArrayReader.ReadVector3();
                                                radi[i] = localPositionArrayReader.ReadSingle();
                                            }
                                        }
                                    }
                                    shape = CreateMultiSphereShape(positions, radi);
                                    break;
                                }
                        }
                        if (shape != null)
                        {
                            shape.LocalScaling = localScaling;
                        }
                        break;
                    }
                case BroadphaseNativeType.TriangleMeshShape:
                    {
                        TriangleIndexVertexArray meshInterface = CreateMeshInterface(shapeData, TriangleMeshShapeData.Offset("MeshInterface"), libPointers);
                        if (meshInterface.NumSubParts == 0)
                        {
                            return null;
                        }
                        OptimizedBvh bvh = null;
                        long bvhPtr = reader.ReadPtr(TriangleMeshShapeData.Offset("QuantizedFloatBvh"));
                        if (bvhPtr != 0)
                        {
                            if (_bvhMap.ContainsKey(bvhPtr))
                            {
                                bvh = _bvhMap[bvhPtr];
                            }
                            else
                            {
                                bvh = CreateOptimizedBvh();
                                throw new NotImplementedException();
                                //bvh.DeserializeFloat(bvhPtr);
                            }
                        }
                        bvhPtr = reader.ReadPtr(TriangleMeshShapeData.Offset("QuantizedDoubleBvh"));
                        if (bvhPtr != 0)
                        {
                            throw new NotImplementedException();
                        }
                        BvhTriangleMeshShape trimeshShape = CreateBvhTriangleMeshShape(meshInterface, bvh);
                        trimeshShape.Margin = reader.ReadSingle(TriangleMeshShapeData.Offset("CollisionMargin"));
                        shape = trimeshShape;
                        break;
                    }
                case BroadphaseNativeType.SoftBodyShape:
                    return null;
                default:
            #if DEBUG
                    Console.WriteLine("Unsupported shape type ({0})\n", type);
            #endif
                    throw new NotImplementedException();
            }

            reader.Dispose();
            stream.Dispose();
            return shape;
        }
        public TriangleIndexVertexArray CreateMeshInterface(byte[] meshData, int offset, Dictionary<long, byte[]> libPointers)
        {
            TriangleIndexVertexArray meshInterface = CreateTriangleMeshContainer();
            byte[] meshParts;
            Vector3 scaling;
            int numMeshParts;
            using (MemoryStream shapeStream = new MemoryStream(meshData, false))
            {
                using (BulletReader shapeReader = new BulletReader(shapeStream))
                {
                    shapeStream.Position += offset;
                    long meshPartsPtr = shapeReader.ReadPtr();
                    meshParts = libPointers[meshPartsPtr];
                    scaling = shapeReader.ReadVector3();
                    numMeshParts = shapeReader.ReadInt32();
                }
            }
            using (MemoryStream meshStream = new MemoryStream(meshParts, false))
            {
                using (BulletReader meshReader = new BulletReader(meshStream))
                {
                    for (int i = 0; i < numMeshParts; i++)
                    {
                        int meshOffset = i * Marshal.SizeOf(typeof(MeshPartData));

                        IndexedMesh meshPart = new IndexedMesh();
                        long vertices3f = meshReader.ReadPtr(meshOffset + MeshPartData.Offset("Vertices3F"));
                        long vertices3d = meshReader.ReadPtr(meshOffset + MeshPartData.Offset("Vertices3D"));
                        long indices32 = meshReader.ReadPtr(meshOffset + MeshPartData.Offset("Indices32"));
                        meshPart.NumTriangles = meshReader.ReadInt32(meshOffset + MeshPartData.Offset("NumTriangles"));
                        meshPart.NumVertices = meshReader.ReadInt32(meshOffset + MeshPartData.Offset("NumVertices"));
                        meshPart.Allocate(meshPart.NumTriangles, meshPart.NumVertices, sizeof(int) * 3, sizeof(float) * 4);

                        if (indices32 != 0)
                        {
                            using (Stream triangleStream = meshPart.GetTriangleStream())
                            {
                                byte[] indices = libPointers[indices32];
                                triangleStream.Write(indices, 0, indices.Length);
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                            long indices16 = meshReader.ReadPtr(meshOffset + MeshPartData.Offset("Indices16"));
                        }

                        if (vertices3f != 0)
                        {
                            using (Stream vertexStream = meshPart.GetVertexStream())
                            {
                                byte[] vertices = libPointers[vertices3f];
                                vertexStream.Write(vertices, 0, vertices.Length);
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        if (meshPart.TriangleIndexBase != IntPtr.Zero && meshPart.VertexBase != IntPtr.Zero)
                        {
                            meshInterface.AddIndexedMesh(meshPart, meshPart.IndexType);
                        }
                        //meshPart.Dispose();
                    }
                }
            }
            return meshInterface;
        }
        protected void ConvertRigidBodyFloat(byte[] bodyData, Dictionary<long, byte[]> libPointers)
        {
            MemoryStream stream = new MemoryStream(bodyData, false);
            BulletReader reader = new BulletReader(stream);

            int cod = RigidBodyFloatData.Offset("CollisionObjectData");
            long collisionShapePtr = reader.ReadPtr(cod + CollisionObjectFloatData.Offset("CollisionShape"));
            Matrix startTransform = reader.ReadMatrix(cod + CollisionObjectFloatData.Offset("WorldTransform"));
            float inverseMass = reader.ReadSingle(RigidBodyFloatData.Offset("InverseMass"));
            long namePtr = reader.ReadPtr(CollisionObjectFloatData.Offset("Name"));

            float mass = inverseMass.Equals(0) ? 0 : 1.0f / inverseMass;
            CollisionShape shape = _shapeMap[collisionShapePtr];

            if (shape.IsNonMoving)
            {
                mass = 0.0f;
            }
            bool isDynamic;
            Vector3 localInertia;
            if (mass != 0.0f)
            {
                isDynamic = true;
                shape.CalculateLocalInertia(mass, out localInertia);
            }
            else
            {
                isDynamic = false;
                localInertia = Vector3.Zero;
            }
            string name = null;
            if (namePtr != 0)
            {
                byte[] nameData = libPointers[namePtr];
                int length = Array.IndexOf(nameData, (byte)0);
                name = System.Text.Encoding.ASCII.GetString(nameData, 0, length);
            }
            RigidBody body = CreateRigidBody(isDynamic, mass, ref startTransform, shape, name);
            _bodyMap.Add(bodyData, body);

            reader.Dispose();
            stream.Dispose();
        }
        protected void ConvertRigidBodyFloat(byte[] bodyData, Dictionary<long, byte[]> libPointers)
        {
            long collisionShapePtr, namePtr;
            Matrix startTransform;
            float inverseMass;
            float friction, restitution;
            Vector3 angularFactor, linearFactor;

            using (var stream = new MemoryStream(bodyData, false))
            {
                using (var reader = new BulletReader(stream))
                {
                    int cod = RigidBodyFloatData.Offset("CollisionObjectData");
                    collisionShapePtr = reader.ReadPtr(cod + CollisionObjectFloatData.Offset("CollisionShape"));
                    startTransform = reader.ReadMatrix(cod + CollisionObjectFloatData.Offset("WorldTransform"));
                    namePtr = reader.ReadPtr(cod + CollisionObjectFloatData.Offset("Name"));
                    friction = reader.ReadSingle(cod + CollisionObjectFloatData.Offset("Friction"));
                    restitution = reader.ReadSingle(cod + CollisionObjectFloatData.Offset("Restitution"));

                    inverseMass = reader.ReadSingle(RigidBodyFloatData.Offset("InverseMass"));
                    angularFactor = reader.ReadVector3(RigidBodyFloatData.Offset("AngularFactor"));
                    linearFactor = reader.ReadVector3(RigidBodyFloatData.Offset("LinearFactor"));
                }
            }

            CollisionShape shape = _shapeMap[collisionShapePtr];

            float mass;
            bool isDynamic;
            if (shape.IsNonMoving)
            {
                mass = 0.0f;
                isDynamic = false;
            }
            else
            {
                isDynamic = inverseMass != 0;
                mass = isDynamic ? 1.0f / inverseMass : 0;
            }
            string name = null;
            if (namePtr != 0)
            {
                byte[] nameData = libPointers[namePtr];
                int length = Array.IndexOf(nameData, (byte)0);
                name = Encoding.ASCII.GetString(nameData, 0, length);
            }

            RigidBody body = CreateRigidBody(isDynamic, mass, ref startTransform, shape, name);
            body.Friction = friction;
            body.Restitution = restitution;
            body.AngularFactor = angularFactor;
            body.LinearFactor = linearFactor;
            _bodyMap.Add(bodyData, body);
        }
Example #15
0
        private void Init(BulletReader reader, bool swap)
        {
            if (swap)
            {
                throw new NotImplementedException();
            }

            Stream stream = reader.BaseStream;

            reader.ReadTag("SDNA");

            // Element names
            reader.ReadTag("NAME");
            string[] names     = reader.ReadStringList();
            var      nameInfos = names
                                 .Select(n => new NameInfo(n))
                                 .ToArray();

            _hasIntType = names.Contains("int");

            // Types
            reader.ReadTag("TYPE");
            string[] typeNames = reader.ReadStringList();
            stream.Position = (stream.Position + 3) & ~3;

            reader.ReadTag("TLEN");
            TypeDecl[] types = typeNames.Select(name =>
            {
                short length = reader.ReadInt16();
                if (_ptrLen == 0 && name == "ListBase")
                {
                    _ptrLen = length / 2;
                }
                return(new TypeDecl(name, length));
            }).ToArray();
            stream.Position = (stream.Position + 3) & ~3;

            // Structs
            reader.ReadTag("STRC");
            int numStructs = reader.ReadInt32();

            _structs          = new StructDecl[numStructs];
            _structByTypeName = new Dictionary <string, StructDecl>(numStructs);
            for (int i = 0; i < numStructs; i++)
            {
                short    typeIndex  = reader.ReadInt16();
                TypeDecl structType = types[typeIndex];

                int numElements = reader.ReadInt16();
                var elements    = new ElementDecl[numElements];
                for (int j = 0; j < numElements; j++)
                {
                    typeIndex = reader.ReadInt16();
                    short nameIndex = reader.ReadInt16();
                    elements[j] = new ElementDecl(types[typeIndex], nameInfos[nameIndex]);
                }

                var structDecl = new StructDecl(structType, elements);
                structType.Struct = structDecl;
                _structs[i]       = structDecl;
                _structByTypeName.Add(structType.Name, structDecl);
            }
        }
        private void AutoSerializeRootLevelChildren(XmlElement parent)
        {
            foreach (XmlNode node in parent)
            {
                if (node.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                XmlElement element = node as XmlElement;
                switch (element.Name)
                {
                    case "btCompoundShapeChildData":
                        DeSerializeCompoundShapeChildData(element);
                        continue;
                    case "btCompoundShapeData":
                        DeSerializeCompoundShapeData(element);
                        continue;
                    case "btConvexHullShapeData":
                        DeSerializeConvexHullShapeData(element);
                        continue;
                    case "btConvexInternalShapeData":
                        DeSerializeConvexInternalShapeData(element);
                        continue;
                    case "btDynamicsWorldFloatData":
                        DeSerializeDynamicsWorldData(element);
                        continue;
                    case "btGeneric6DofConstraintData":
                        DeSerializeGeneric6DofConstraintData(element);
                        continue;
                    case "btRigidBodyFloatData":
                        DeSerializeRigidBodyFloatData(element);
                        continue;
                    case "btStaticPlaneShapeData":
                        DeSerializeStaticPlaneShapeData(element);
                        continue;
                    case "btVector3FloatData":
                        DeSerializeVector3FloatData(element);
                        continue;
                    default:
                        throw new NotImplementedException();
                }
            }

            foreach (byte[] shapeData in _collisionShapeData)
            {
                CollisionShape shape = ConvertCollisionShape(shapeData, _pointerLookup);
                if (shape != null)
                {
                    foreach (KeyValuePair<long, byte[]> lib in _pointerLookup)
                    {
                        if (lib.Value == shapeData)
                        {
                            _shapeMap.Add(lib.Key, shape);
                            break;
                        }
                    }

                    using (var stream = new MemoryStream(shapeData, false))
                    {
                        using (var reader = new BulletReader(stream))
                        {
                            long namePtr = reader.ReadPtr(CollisionShapeFloatData.Offset("Name"));
                            if (namePtr != 0)
                            {
                                byte[] nameData = _pointerLookup[namePtr];
                                int length = Array.IndexOf(nameData, (byte)0);
                                string name = System.Text.Encoding.ASCII.GetString(nameData, 0, length);
                                _objectNameMap.Add(shape, name);
                                _nameShapeMap.Add(name, shape);
                            }
                        }
                    }
                }
            }

            foreach (byte[] rbData in _rigidBodyData)
            {
                ConvertRigidBodyFloat(rbData, _pointerLookup);
            }

            foreach (byte[] constraintData in _constraintData)
            {
                //throw new NotImplementedException();
                //ConvertConstraint(constraintData);
            }
        }
 private void InitDna()
 {
     _dnaData = IntPtr.Size == 8 ? GetBulletDna64() : GetBulletDna();
     bool swap = !BitConverter.IsLittleEndian;
     using (var stream = new MemoryStream(_dnaData))
     {
         using (var reader = new BulletReader(stream))
         {
             _dna = Dna.Load(reader, swap);
         }
     }
 }
Example #18
0
 public static Dna Load(BulletReader dnaReader, bool swap)
 {
     var dna = new Dna();
     dna.Init(dnaReader, swap);
     return dna;
 }
Example #19
0
        private void Init(BulletReader reader, bool swap)
        {
            if (swap)
            {
                throw new NotImplementedException();
            }

            Stream stream = reader.BaseStream;
            reader.ReadTag("SDNA");

            // Element names
            reader.ReadTag("NAME");
            string[] names = reader.ReadStringList();
            var nameInfos = names
                .Select(n => new NameInfo(n))
                .ToArray();
            _hasIntType = names.Contains("int");

            // Types
            reader.ReadTag("TYPE");
            string[] typeNames = reader.ReadStringList();
            stream.Position = (stream.Position + 3) & ~3;

            reader.ReadTag("TLEN");
            TypeDecl[] types = typeNames.Select(name =>
            {
                short length = reader.ReadInt16();
                if (_ptrLen == 0 && name == "ListBase")
                {
                    _ptrLen = length / 2;
                }
                return new TypeDecl(name, length);
            }).ToArray();
            stream.Position = (stream.Position + 3) & ~3;

            // Structs
            reader.ReadTag("STRC");
            int numStructs = reader.ReadInt32();
            _structs = new StructDecl[numStructs];
            _structByTypeName = new Dictionary<string, StructDecl>(numStructs);
            for (int i = 0; i < numStructs; i++)
            {
                short typeIndex = reader.ReadInt16();
                TypeDecl structType = types[typeIndex];

                int numElements = reader.ReadInt16();
                var elements = new ElementDecl[numElements];
                for (int j = 0; j < numElements; j++)
                {
                    typeIndex = reader.ReadInt16();
                    short nameIndex = reader.ReadInt16();
                    elements[j] = new ElementDecl(types[typeIndex], nameInfos[nameIndex]);
                }

                var structDecl = new StructDecl(structType, elements);
                structType.Struct = structDecl;
                _structs[i] = structDecl;
                _structByTypeName.Add(structType.Name, structDecl);
            }
        }