Example #1
0
        /// <summary>
        /// Sets the facing of the cell
        /// </summary>
        /// <param name="direction"></param>
        public void Reorientate(Vector3 direction)
        {
            direction.unitVect();

            orientation.x = direction.x;
            orientation.y = direction.y;
            orientation.z = direction.z;
        }
Example #2
0
        /// <summary>
        /// Private method for performing the spatial simulation.
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="currentState"></param>
        /// <param name="time"></param>
        /// <param name="StepTime"></param>
        private void SpatialSimulator(CellInstance cell, StateSnapshot currentState, double time, double StepTime)
        {
            Vector3 p = cell.CellInstanceSpatialContext.Position;
            Vector3 v = cell.CellInstanceSpatialContext.Velocity;
            Vector3 ang = cell.CellInstanceSpatialContext.Orientation;
            float visc = currentState.SimulationEnvironment.Viscosity;
            float h = (float)StepTime;

            //viscous drag (Stokes's drag)
            v.x += -visc * h * v.x * 1.5f;
            v.y += -visc * h * v.y * 1.5f;
            v.z += -visc * h * v.z * 1.5f;

            //cell collisions
            if (currentState.SimulationEnvironment.EnableCellCollisions)
            {
                foreach (CellInstance cellB in currentState.Cells)
                {
                    if (cell != cellB) //avoid collision with self
                    {
                        //the vector from the centre of this cell to cellB
                        Vector3 dist = new Vector3(p.x - cellB.CellInstanceSpatialContext.Position.x,
                                                   p.y - cellB.CellInstanceSpatialContext.Position.y,
                                                   p.z - cellB.CellInstanceSpatialContext.Position.z);
                        float distMag = dist.magnitude();

                        if (distMag < cell.CellInstanceSpatialContext.Radius*0.001 + cellB.CellInstanceSpatialContext.Radius*0.001)
                        {
                            /*
                             * Collision occured: accelerate this cell away from the centre of the cell it is colliding with:
                             */

                            dist.unitVect(); //normalize
                            dist.x *= -h*0.1f;
                            dist.y *= -h*0.1f;
                            dist.z *= -h*0.1f;

                            //accelerate this cell and the one it collided with in oppose directions:
                            v.x -= dist.x;
                            v.y -= dist.y;
                            v.z -= dist.z;
                            cellB.CellInstanceSpatialContext.Accelerate(dist);

                        }

                    }
                }

            }

            //positional change
            p.x += v.x * h;
            p.y += v.y * h;
            p.z += v.z * h;

            //check that boundary conditions are maintained (most of the time this will be true, and will be the only test needed)
            if (!currentState.SimulationEnvironment.Boundary.InsideBoundary(p))
            {
                /*
                 * If the cell is not inside the environment boundary, we move it back
                 * and attempt to move the cell by individual components (this allows
                 * the cell to "slide" along the edges of the boundary without
                 * breaking the boundary conditions). In most cases these three boundary
                 * checks should not be necessary
                 */

                //begin by checking x component, so move back y and z components
                p.y -= v.y * h;
                p.z -= v.z * h;
                if (!currentState.SimulationEnvironment.Boundary.InsideBoundary(p))
                {
                    //x failed, so move back x
                    p.x -= v.x * h;
                }

                //check y component
                p.y += v.y * h;
                if (!currentState.SimulationEnvironment.Boundary.InsideBoundary(p))
                {
                    //y failed
                    p.y -= v.y * h;
                }

                //check z component
                p.z += v.z * h;
                if (!currentState.SimulationEnvironment.Boundary.InsideBoundary(p))
                {
                    //z failed
                    p.z -= v.z * h;
                }

            }

            cell.CellInstanceSpatialContext.Position = p;
            cell.CellInstanceSpatialContext.Velocity = v;
            cell.CellInstanceSpatialContext.Orientation = ang;
        }