Esempio n. 1
0
        public static bool FindRandomTreeInPlaceArea(long entityId, out ItemInfo result)
        {
            result = default(ItemInfo);

            MyPlaceArea area = MyPlaceArea.FromEntity(entityId);

            if (area == null)
            {
                return(false);
            }

            var             areaBoundingBox = area.WorldAABB;
            List <MyEntity> entities        = null;

            try
            {
                entities = MyEntities.GetEntitiesInAABB(ref areaBoundingBox);

                m_tmpItemInfoList.Clear();
                foreach (var entity in entities)
                {
                    MyTrees trees = entity as MyTrees;
                    if (trees == null)
                    {
                        continue;
                    }

                    m_tmpEnvItemList.Clear();
                    trees.GetPhysicalItemsInRadius(areaBoundingBox.Center, (float)areaBoundingBox.HalfExtents.Length(), m_tmpEnvItemList);
                    foreach (var tree in m_tmpEnvItemList)
                    {
                        if (area.TestPoint(tree.Transform.Position))
                        {
                            var itemInfo = new ItemInfo();
                            itemInfo.ItemsEntityId = trees.EntityId;
                            itemInfo.ItemId        = tree.LocalId;
                            itemInfo.Target        = tree.Transform.Position;
                            m_tmpItemInfoList.Add(itemInfo);
                        }
                    }
                    m_tmpEnvItemList.Clear();
                }

                if (m_tmpItemInfoList.Count == 0)
                {
                    m_tmpItemInfoList.Clear();
                    return(false);
                }

                int treeIndex = (int)Math.Round(MyRandom.Instance.NextFloat() * (m_tmpItemInfoList.Count - 1));
                result = m_tmpItemInfoList[treeIndex];
                m_tmpItemInfoList.Clear();

                return(true);
            }
            finally
            {
                entities.Clear();
            }
        }
        private static void GetSafeBoundingBoxForPlayers(Vector3D start, double spawnDistance, out BoundingBoxD output)
        {
            double          tolerance = 10.0f;
            BoundingSphereD sphere    = new BoundingSphereD(start, tolerance);

            var  players = MySession.Static.Players.GetOnlinePlayers();
            bool tryIncludeOtherPlayers = true;

            // We have to try adding other players until the bounding sphere stays the same
            while (tryIncludeOtherPlayers)
            {
                tryIncludeOtherPlayers = false;
                foreach (var player in players)
                {
                    Vector3D playerPosition     = player.GetPosition();
                    double   distanceFromSphere = (sphere.Center - playerPosition).Length() - sphere.Radius;

                    if (distanceFromSphere <= 0.0)
                    {
                        continue;
                    }
                    if (distanceFromSphere > spawnDistance * 2.0f)
                    {
                        continue;
                    }

                    sphere.Include(new BoundingSphereD(playerPosition, tolerance));
                    tryIncludeOtherPlayers = true;
                }
            }

            sphere.Radius += spawnDistance;
            output         = new BoundingBoxD(sphere.Center - new Vector3D(sphere.Radius), sphere.Center + new Vector3D(sphere.Radius));

            var entities = MyEntities.GetEntitiesInAABB(ref output);

            foreach (var entity in entities)
            {
                if (entity is MyCubeGrid)
                {
                    var cubeGrid = entity as MyCubeGrid;
                    if (cubeGrid.IsStatic)
                    {
                        Vector3D gridPosition = cubeGrid.PositionComp.GetPosition();

                        // If grid is close to picked player we need to include it's "safe" bounding box for spawning ships,
                        // so cargo ships don't spawn near it.

                        output.Include(new BoundingBoxD(new Vector3D(gridPosition - spawnDistance), new Vector3D(gridPosition + spawnDistance)));
                    }
                }
            }
            entities.Clear();
        }
        List <IMyEntity> IMyEntities.GetEntitiesInAABB(ref VRageMath.BoundingBoxD boundingBox)
        {
            var lst    = MyEntities.GetEntitiesInAABB(ref boundingBox);
            var result = new List <IMyEntity>(lst.Count);

            foreach (var entity in lst)
            {
                result.Add(entity);
            }
            return(result);
        }
Esempio n. 4
0
        public static bool FindClosestTreeInPlaceArea(Vector3D fromPosition, long entityId, MyHumanoidBot bot, out ItemInfo result)
        {
            result = default(ItemInfo);
            MyPlaceArea area = MyPlaceArea.FromEntity(entityId);

            if (area == null)
            {
                return(false);
            }

            var areaBoundingBox = area.WorldAABB;
            var entities        = MyEntities.GetEntitiesInAABB(ref areaBoundingBox, true);

            double closestDistanceSq = double.MaxValue;

            foreach (MyEntity entity in entities)
            {
                MyTrees trees = entity as MyTrees;
                if (trees == null)
                {
                    continue;
                }

                m_tmpEnvItemList.Clear();
                trees.GetPhysicalItemsInRadius(areaBoundingBox.Center, (float)areaBoundingBox.HalfExtents.Length(), m_tmpEnvItemList);

                foreach (var tree in m_tmpEnvItemList)
                {
                    if (!area.TestPoint(tree.Transform.Position))
                    {
                        continue;
                    }

                    if (!bot.AgentLogic.AiTarget.IsTreeReachable(entity, tree.LocalId))
                    {
                        continue;
                    }

                    double distanceSq = Vector3D.DistanceSquared(fromPosition, tree.Transform.Position);
                    if (distanceSq < closestDistanceSq)
                    {
                        result.ItemsEntityId = entity.EntityId;
                        result.ItemId        = tree.LocalId;
                        result.Target        = tree.Transform.Position;
                        closestDistanceSq    = distanceSq;
                    }
                }
                m_tmpEnvItemList.Clear();
            }

            entities.Clear();

            return(closestDistanceSq != double.MaxValue);
        }
Esempio n. 5
0
        public override void AccumulateCorrection(ref Vector3 correction, ref float weight)
        {
            if (Parent.Speed < 0.01f)
            {
                return;
            }

            var characterBotEntity = Parent.BotEntity as MyCharacter; // remove me pls

            if (characterBotEntity == null)
            {
                return;
            }

            var          position        = Parent.PositionAndOrientation.Translation;
            BoundingBoxD box             = new BoundingBoxD(position - Vector3D.One * 3, position + Vector3D.One * 3);
            Vector3D     currentMovement = Parent.ForwardVector;

            var entities = MyEntities.GetEntitiesInAABB(ref box);

            foreach (var entity in entities)
            {
                var character = entity as MyCharacter;
                if (character == null || character == characterBotEntity)
                {
                    continue;
                }
                if (character.ModelName == characterBotEntity.ModelName) // remove me pls
                {
                    continue;
                }

                Vector3D characterPos = character.PositionComp.GetPosition();
                Vector3D dir          = characterPos - position;
                double   dist         = dir.Normalize();
                dist = MathHelper.Clamp(dist, 0, 6);
                var cos = Vector3D.Dot(dir, currentMovement);

                var opposite = -dir;
                if (cos > -0.807)
                {
                    correction += (6f - dist) * Weight * opposite;
                }

                if (!correction.IsValid())
                {
                    System.Diagnostics.Debugger.Break();
                }
            }
            entities.Clear();
            weight += Weight;
        }
Esempio n. 6
0
        protected override void ReadEntitiesInRange()
        {
            m_entitiesInRange.Clear();

            MyOrientedBoundingBox bbox = new MyOrientedBoundingBox(Center, m_halfExtents, m_orientation);
            var aabb = bbox.GetAABB();
            var res  = MyEntities.GetEntitiesInAABB(ref aabb);

            for (int i = 0; i < res.Count; ++i)
            {
                var rootEntity = res[i].GetTopMostParent();
                if (!IgnoredEntities.Contains(rootEntity))
                {
                    m_entitiesInRange[rootEntity.EntityId] = new DetectionInfo(rootEntity, FrontPoint);
                }
            }
            res.Clear();
        }
Esempio n. 7
0
 public override void AccumulateCorrection(ref Vector3 correction, ref float weight)
 {
     if (base.Parent.Speed >= 0.01f)
     {
         MyCharacter botEntity = base.Parent.BotEntity as MyCharacter;
         if (botEntity != null)
         {
             Vector3D        translation    = base.Parent.PositionAndOrientation.Translation;
             BoundingBoxD    boundingBox    = new BoundingBoxD(translation - (Vector3D.One * 3.0), translation + (Vector3D.One * 3.0));
             Vector3D        forwardVector  = base.Parent.ForwardVector;
             List <MyEntity> entitiesInAABB = MyEntities.GetEntitiesInAABB(ref boundingBox, false);
             foreach (MyCharacter character2 in entitiesInAABB)
             {
                 if (character2 == null)
                 {
                     continue;
                 }
                 if (!ReferenceEquals(character2, botEntity) && (character2.ModelName != botEntity.ModelName))
                 {
                     Vector3D vectord3 = character2.PositionComp.GetPosition() - translation;
                     double   num      = MathHelper.Clamp(vectord3.Normalize(), 0.0, 6.0);
                     Vector3D vectord4 = -vectord3;
                     if (Vector3D.Dot(vectord3, forwardVector) > -0.807)
                     {
                         correction += ((6.0 - num) * base.Weight) * vectord4;
                     }
                     if (!correction.IsValid())
                     {
                         Debugger.Break();
                     }
                 }
             }
             entitiesInAABB.Clear();
             weight += base.Weight;
         }
     }
 }
        public override void AccumulateCorrection(ref VRageMath.Vector3 correction, ref float weight)
        {
            Vector3D position = Parent.PositionAndOrientation.Translation;

            BoundingBoxD box = new BoundingBoxD(position - Vector3D.One, position + Vector3D.One);

            Vector3D currentMovement = Parent.ForwardVector * Parent.Speed;

            if (Parent.Speed > 0.01f)
            {
                currentMovement.Normalize();
            }

            // Don't do any correction if we're not moving
            if (currentMovement.LengthSquared() < 0.01)
            {
                return;
            }

            var entities = MyEntities.GetEntitiesInAABB(ref box);

            foreach (var entity in entities)
            {
                var environmentItems = entity as MyEnvironmentItems;
                if (environmentItems == null)
                {
                    continue;
                }

                environmentItems.GetItemsInRadius(ref position, 6.0f, m_trees);

                foreach (var item in m_trees)
                {
                    Vector3D dir  = item - position;
                    var      dist = dir.Normalize();
                    dir = Vector3D.Reject(currentMovement, dir);

                    dir.Y = 0.0f;
                    if (dir.Z * dir.Z + dir.X * dir.X < 0.1)
                    {
                        Vector3D dirLocal = Vector3D.TransformNormal(dir, Parent.PositionAndOrientationInverted);
                        dir = position - item;
                        dir = Vector3D.Cross(Vector3D.Up, dir);
                        if (dirLocal.X < 0)
                        {
                            dir = -dir;
                        }
                    }

                    dir.Normalize();

                    correction += (6f - dist) * Weight * dir;
                    if (!correction.IsValid())
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                }
                m_trees.Clear();
            }

            weight += Weight;

            entities.Clear();
        }
Esempio n. 9
0
        public static bool FindRandomCollectableItemInPlaceArea(long entityId, HashSet <MyDefinitionId> itemDefinitions, out ComponentInfo result)
        {
            result         = default(ComponentInfo);
            result.IsBlock = true;

            MyPlaceArea area = MyPlaceArea.FromEntity(entityId);

            if (area == null)
            {
                return(false);
            }

            var             areaBoundingBox = area.WorldAABB;
            List <MyEntity> entities        = null;

            try
            {
                entities = MyEntities.GetEntitiesInAABB(ref areaBoundingBox);

                for (int i = entities.Count - 1; i >= 0; i--)
                {
                    var entity = entities[i];

                    if (MyManipulationTool.IsEntityManipulated(entity))
                    {
                        entities.RemoveAtFast(i);
                        continue;
                    }

                    var cubeGrid = entity as MyCubeGrid;
                    var fo       = entity as MyFloatingObject;
                    if (fo == null && (cubeGrid == null || cubeGrid.BlocksCount != 1))
                    {
                        entities.RemoveAtFast(i);
                        continue;
                    }

                    if (cubeGrid != null)
                    {
                        MySlimBlock first = cubeGrid.CubeBlocks.First();
                        if (!itemDefinitions.Contains(first.BlockDefinition.Id))
                        {
                            entities.RemoveAtFast(i);
                            continue;
                        }
                    }
                    else if (fo != null)
                    {
                        var id = fo.Item.Content.GetId();
                        if (!itemDefinitions.Contains(id))
                        {
                            entities.RemoveAtFast(i);
                            continue;
                        }
                    }
                }

                if (entities.Count() == 0)
                {
                    return(false);
                }

                int randIdx        = (int)Math.Round(MyRandom.Instance.NextFloat() * (entities.Count() - 1));
                var selectedEntity = entities[randIdx];
                result.EntityId = selectedEntity.EntityId;

                if (selectedEntity is MyCubeGrid)
                {
                    var selectedCube = selectedEntity as MyCubeGrid;
                    var first        = selectedCube.GetBlocks().First();

                    result.EntityId              = selectedCube.EntityId;
                    result.BlockPosition         = first.Position;
                    result.ComponentDefinitionId = GetComponentId(first);
                    result.IsBlock = true;
                }
                else
                {
                    result.IsBlock = false;
                }

                return(true);
            }
            finally
            {
                entities.Clear();
            }
        }
Esempio n. 10
0
        public static bool FindClosestCollectableItemInPlaceArea(Vector3D fromPosition, long entityId, HashSet <MyDefinitionId> itemDefinitions, out ComponentInfo result)
        {
            List <MyEntity> entities = null;

            result = default(ComponentInfo);

            try
            {
                MyEntity    containingEntity = null;
                MyPlaceArea area             = null;

                if (!MyEntities.TryGetEntityById(entityId, out containingEntity))
                {
                    return(false);
                }
                if (!containingEntity.Components.TryGet <MyPlaceArea>(out area))
                {
                    return(false);
                }

                var areaBoundingBox = area.WorldAABB;
                entities = MyEntities.GetEntitiesInAABB(ref areaBoundingBox);

                MyEntity    closestObject           = null;
                MySlimBlock first                   = null;
                double      closestObjectDistanceSq = double.MaxValue;
                bool        closestIsBlock          = false;

                foreach (var entity in entities)
                {
                    if (MyManipulationTool.IsEntityManipulated(entity))
                    {
                        continue;
                    }

                    if (entity is MyCubeGrid)
                    {
                        var cubeGrid = entity as MyCubeGrid;
                        if (cubeGrid.BlocksCount == 1)
                        {
                            first = cubeGrid.CubeBlocks.First();
                            if (itemDefinitions.Contains(first.BlockDefinition.Id))
                            {
                                var worldPosition = cubeGrid.GridIntegerToWorld(first.Position);
                                var cubeDistanceFromCharacterSq = Vector3D.DistanceSquared(worldPosition, fromPosition);

                                if (cubeDistanceFromCharacterSq < closestObjectDistanceSq)
                                {
                                    closestObjectDistanceSq = cubeDistanceFromCharacterSq;
                                    closestObject           = cubeGrid;
                                    closestIsBlock          = true;
                                }
                            }
                        }
                    }

                    if (entity is MyFloatingObject)
                    {
                        var fo = entity as MyFloatingObject;
                        var id = fo.Item.Content.GetId();
                        if (itemDefinitions.Contains(id))
                        {
                            var foToPlayerDistSq = Vector3D.DistanceSquared(fo.PositionComp.WorldMatrix.Translation, fromPosition);
                            if (foToPlayerDistSq < closestObjectDistanceSq)
                            {
                                closestObjectDistanceSq = foToPlayerDistSq;
                                closestObject           = fo;
                                closestIsBlock          = false;
                            }
                        }
                    }
                }

                if (closestObject == null)
                {
                    return(false);
                }

                result.IsBlock  = closestIsBlock;
                result.EntityId = closestObject.EntityId;
                if (closestIsBlock)
                {
                    result.BlockPosition         = first.Position;
                    result.ComponentDefinitionId = GetComponentId(first);
                }

                return(true);
            }
            finally
            {
                if (entities != null)
                {
                    entities.Clear();
                }
            }
        }
        protected override void OnLoad(BitStream stream, Action <MyVoxelBase> loadingDoneHandler)
        {
            MyVoxelBase voxelMap;

            bool isUserCreated = VRage.Serialization.MySerializer.CreateAndRead <bool>(stream);
            bool isFromPrefab  = VRage.Serialization.MySerializer.CreateAndRead <bool>(stream);
            bool rangeChanged  = VRage.Serialization.MySerializer.CreateAndRead <bool>(stream);

            byte[] data         = null;
            string asteroidName = null;

            if (rangeChanged)
            {
                data = VRage.Serialization.MySerializer.CreateAndRead <byte[]>(stream);
            }
            else if (isUserCreated)
            {
                asteroidName = VRage.Serialization.MySerializer.CreateAndRead <string>(stream);
            }

            if (isFromPrefab)
            {
                var builder = VRage.Serialization.MySerializer.CreateAndRead <MyObjectBuilder_EntityBase>(stream, MyObjectBuilderSerializer.Dynamic);

                if (rangeChanged && data != null)
                {
                    IMyStorage storage = MyStorageBase.Load(data);
                    if (MyEntities.TryGetEntityById <MyVoxelBase>(builder.EntityId, out voxelMap))
                    {
                        if (voxelMap is MyVoxelMap)
                        {
                            ((MyVoxelMap)voxelMap).Storage = storage;
                        }
                        else if (voxelMap is MyPlanet)
                        {
                            ((MyPlanet)voxelMap).Storage = storage;
                        }
                        else
                        {
                            Debug.Fail("Unknown voxel kind");
                        }
                    }
                    else
                    {
                        voxelMap = (MyVoxelBase)MyEntities.CreateFromObjectBuilderNoinit(builder);
                        if (voxelMap is MyVoxelMap)
                        {
                            ((MyVoxelMap)voxelMap).Init(builder, storage);
                        }
                        else if (voxelMap is MyPlanet)
                        {
                            ((MyPlanet)voxelMap).Init(builder, storage);
                        }
                        else
                        {
                            Debug.Fail("Unknown voxel kind");
                        }
                        if (voxelMap != null)
                        {
                            MyEntities.Add(voxelMap);
                        }
                    }
                }
                else if (isUserCreated)
                {
                    TryRemoveExistingEntity(builder.EntityId);

                    IMyStorage storage = MyGuiScreenDebugSpawnMenu.CreateAsteroidStorage(asteroidName, 0);
                    voxelMap = (MyVoxelBase)MyEntities.CreateFromObjectBuilderNoinit(builder);
                    if (voxelMap is MyVoxelMap)
                    {
                        ((MyVoxelMap)voxelMap).Init(builder, storage);
                    }
                    if (voxelMap != null)
                    {
                        MyEntities.Add(voxelMap);
                    }
                }
                else
                {
                    TryRemoveExistingEntity(builder.EntityId);

                    voxelMap = (MyVoxelBase)MyEntities.CreateFromObjectBuilderNoinit(builder);
                    if (voxelMap != null)
                    {
                        voxelMap.Init(builder);
                        MyEntities.Add(voxelMap);
                    }
                }
            }
            else
            {
                long voxelMapId = VRage.Serialization.MySerializer.CreateAndRead <long>(stream);
                MyEntities.TryGetEntityById <MyVoxelBase>(voxelMapId, out voxelMap);
            }

            if (voxelMap != null)
            {
                BoundingBoxD voxelBox = new BoundingBoxD(voxelMap.PositionLeftBottomCorner, voxelMap.PositionLeftBottomCorner + voxelMap.SizeInMetres);
                m_entities = MyEntities.GetEntitiesInAABB(ref voxelBox);
                foreach (var entity in m_entities)
                {
                    MyVoxelBase voxel = entity as MyVoxelBase;
                    if (voxel != null)
                    {
                        if (voxel.Save == false && voxel != voxelMap)
                        {
                            voxel.Close();
                            break;
                        }
                    }
                }
                m_entities.Clear();
            }

            loadingDoneHandler(voxelMap);
        }
        public void Render()
        {
            if (MyAPIGateway.Utilities.IsDedicated)
            {
                return;
            }
            var gravity = Vector3.TransformNormal(MyGravityProviderSystem.CalculateTotalGravityInPoint(Entity.GetPosition()),
                                                  Entity.PositionComp.WorldMatrixNormalizedInv);
            Vector3 windDir      = Vector3.TransformNormal(WindVector, Entity.PositionComp.WorldMatrixNormalizedInv);
            float   windStrength = 0;
            {
                var freq  = new Vector4(1.975f, 0.973f, 0.375f, 0.193f);
                var x     = (float)MySession.Static.ElapsedGameTime.TotalSeconds * WindStrength + (float)((Vector3D)WindVector).Dot(Entity.GetPosition());
                var waves = freq * x;
                waves = new Vector4(Math.Abs(((waves.X + 0.5f) % 1) * 2 - 1), Math.Abs(((waves.Y + 0.5f) % 1) * 2 - 1),
                                    Math.Abs(((waves.Z + 0.5f) % 1) * 2 - 1), Math.Abs(((waves.W + 0.5f) % 1) * 2 - 1));
                waves = waves * waves * (new Vector4(3) - new Vector4(2) * waves);

                windStrength = (waves.X + waves.Y + waves.Z + waves.W) * 0.25f;
            }


            var parent          = Entity;
            var parentRenderObj = parent.Get <MyRenderComponentBase>();

            while (parentRenderObj == null && parent != null)
            {
                parent          = parent.Parent;
                parentRenderObj = parent.Get <MyRenderComponentBase>();
            }

            if (parentRenderObj == null)
            {
                return;
            }

            var skeleton = Entity.Get <MySkeletonComponent>();

            if (_prevTickPosition.HasValue)
            {
                var pp = _prevTickPosition.Value;
                // Apply a transform to the cloth such that:  transform(CurrentPos, ClothDataNew) == transform(PrevPos, ClothDataOld)
                var transform = (Matrix)(pp * Entity.PositionComp.WorldMatrixInvScaled);
                foreach (var cloth in _cloths)
                {
                    cloth.ApplyTransform(transform);
                }
            }

            _prevTickPosition = Entity.PositionComp.WorldMatrix;
            for (var id = 0; id < _cloths.Length; id++)
            {
                var cloth   = _cloths[id];
                var section = Definition.Quads[id];
                if (skeleton != null)
                {
                    foreach (var binding in section.Bindings)
                    {
                        int boneIndex;
                        var bone = skeleton.FindBone(binding.Bone, out boneIndex);
                        if (bone == null)
                        {
                            continue;
                        }

                        for (var yo = 0; yo < binding.YCount; yo++)
                        {
                            var by = binding.Y + yo;
                            var fy = by / (float)(section.Def.ResY - 1);
                            var p0 = Vector3.Lerp(section.Def.V00, section.Def.V01, fy);
                            var p1 = Vector3.Lerp(section.Def.V10, section.Def.V11, fy);
                            for (var xo = 0; xo < binding.XCount; xo++)
                            {
                                var bx         = binding.X + xo;
                                var idx        = section.Def.ResX * by + bx;
                                var fx         = bx / (float)(section.Def.ResX - 1);
                                var bindPos    = Vector3.Lerp(p0, p1, fx);
                                var bindPosRel = Vector3.Transform(bindPos, ref bone.Transform.AbsoluteBindTransformInv);
                                var currPos    = Vector3.Transform(bindPosRel, ref skeleton.BoneAbsoluteTransforms[boneIndex]);
                                cloth.Particles[idx].Position = currPos;
                            }
                        }
                    }
                }

                var region      = (BoundingBoxD)cloth.CalculateInflatedBox(MyEngineConstants.UPDATE_STEPS_PER_SECOND * 2f);
                var regionWorld = region.TransformFast(Entity.PositionComp.WorldMatrix);
                var entities    = MyEntities.GetEntitiesInAABB(ref regionWorld);
                cloth.SphereColliders.Clear();
                cloth.CapsuleColliders.Clear();
                var invWorld = Entity.PositionComp.WorldMatrixInvScaled;
                foreach (var ent in entities)
                {
                    foreach (var collider in ent.Components.GetComponents <ClothColliderComponent>())
                    {
                        Cloth.Sphere[]  spheres;
                        Cloth.Capsule[] capsules;
                        collider.GetColliders(out spheres, out capsules);
                        var conv = (Matrix)(ent.WorldMatrix * invWorld);
                        foreach (var s in spheres)
                        {
                            cloth.SphereColliders.Add(new Cloth.Sphere(Vector3.Transform(s.P0, conv), s.Radius));
                        }
                        foreach (var c in capsules)
                        {
                            cloth.CapsuleColliders.Add(new Cloth.Capsule(new Line
                            {
                                From        = Vector3.Transform(c.Line.From, conv),
                                To          = Vector3.Transform(c.Line.To, conv),
                                Direction   = Vector3.TransformNormal(c.Line.Direction, conv),
                                Length      = c.Line.Length,
                                BoundingBox = c.Line.BoundingBox
                            }, c.Radius));
                        }
                    }
                }

                cloth.Gravity       = gravity;
                cloth.WindDirection = windDir;
                cloth.WindStrength  = windStrength;
                cloth.Simulate();

                var qs  = cloth.QuadStream;
                var pts = cloth.Particles;
                for (var i = 0; i < qs.Length; i += 4)
                {
//                    var quad = new MyQuadD
//                    {
//                        Point0 = pts[qs[i]].Position,
//                        Point1 = pts[qs[i + 1]].Position,
//                        Point2 = pts[qs[i + 2]].Position,
//                        Point3 = pts[qs[i + 3]].Position
//                    };
//                    MyTransparentGeometry.AddAttachedQuad(_mtl, ref quad, Vector4.One, ref quad.Point0, parentRenderObj.GetRenderObjectID());
                    var pt0 = pts[qs[i]];
                    var pt1 = pts[qs[i + 1]];
                    var pt2 = pts[qs[i + 2]];
                    var pt3 = pts[qs[i + 3]];
                    MyTransparentGeometry.AddTriangleBillboard(pt0.Position, pt1.Position, pt2.Position, -pt0.Normal, -pt1.Normal, -pt2.Normal, pt0.Uv, pt1.Uv,
                                                               pt2.Uv, _mtl, parentRenderObj.GetRenderObjectID(), pt0.Position);

                    MyTransparentGeometry.AddTriangleBillboard(pt0.Position, pt2.Position, pt3.Position, -pt0.Normal, -pt2.Normal, -pt3.Normal, pt0.Uv, pt2.Uv,
                                                               pt3.Uv, _mtl, parentRenderObj.GetRenderObjectID(), pt3.Position);
//                    quad.Point0 = Vector3D.Transform(quad.Point0, Entity.WorldMatrix);
//                    quad.Point1 = Vector3D.Transform(quad.Point1, Entity.WorldMatrix);
//                    quad.Point2 = Vector3D.Transform(quad.Point2, Entity.WorldMatrix);
//                    quad.Point3 = Vector3D.Transform(quad.Point3, Entity.WorldMatrix);
//                    MyTransparentGeometry.AddQuad(_mtl, ref quad, Vector4.One, ref quad.Point0);
                }
            }

            _initialRun = false;
        }