Example #1
0
        private void UpdateGeneralTask()
        {
            const float wayPointCheckDistance = 10;

            float wayPointDistance = (this.Position -
                                      CurrentWayPoint.Position).LengthFast();

            if (wayPointDistance < wayPointCheckDistance)
            {
                //next way point or start again from the 1 point

                int index = TaskWay.Points.IndexOf(CurrentWayPoint);
                index++;

                if (index < TaskWay.Points.Count)
                {
                    //next way point
                    CurrentWayPoint = TaskWay.Points[index];
                }
                else
                {
                    CurrentWayPoint = TaskWay.Points[0];
                }
            }

            if (CurrentWayPoint != null)
            {
                DoMoveTask(CurrentWayPoint.Position);
            }
        }
Example #2
0
        void Task(MapCurve way)
        {
            task_way = way;
            task_current_waypoint = null;

            if (task_way != null)
            {
                task_current_waypoint = task_way;
            }

            ResetTask();
        }
        private void DoGeneralTask(GeneralTaskTypes type, MapCurve way)
        {
            generalTaskType            = type;
            generalTaskWay             = way;
            generalTaskCurrentWayPoint = null;

            if (generalTaskWay != null)
            {
                generalTaskCurrentWayPoint = generalTaskWay;
            }

            //if( generalTaskType == GeneralTaskTypes.None )
            ResetMoveTask();
        }
Example #4
0
        private void DoGeneralTask(MapCurve way)
        {
            TaskWay         = way;
            CurrentWayPoint = null;

            if (TaskWay != null && CurrentWayPoint == null)
            {
                CurrentWayPoint = TaskWay;
            }
            if (CurrentWayPoint != null)
            {
                firstWay = false;
            }
        }
Example #5
0
        private void GetMapCameraCurvePoint(out MapCurvePoint point, float MapCameraCurvePointTime)
        {
            point = null;
            //MapCameraCurvePointTime = 0;
            MapCurve mapCurve = (MapCurve)Entities.Instance.GetByName("MM_Curve");

            //MapCameraCurvePoint curvepoint;

            //for(int i = 0; i < mapCurve.Points.Count; i++)
            foreach (MapCurvePoint curvepoint in mapCurve.Points)
            {
                //curvepoint = mapCurve.Points.

                if (curvepoint.Time >= mapCurve.GetCurveTimeRange().Minimum&&
                    curvepoint.Time >= mapCurve.GetCurveTimeRange().Maximum)
                {
                    point = curvepoint;
                    return;
                }
            }
        }
Example #6
0
        void UpdateTask()
        {
            const float waypoint_check_distance = 20;
            float       waypoint_distance       = (ControlledObject.Position -
                                                   task_current_waypoint.Position).Length();

            if (waypoint_distance <= waypoint_check_distance)
            {
                int index = task_way.Points.IndexOf(task_current_waypoint);
                index++;

                if (index < task_way.Points.Count)
                {
                    task_current_waypoint = task_way.Points[index];
                }
                else
                {
                    task_current_waypoint = task_way.Points[0];
                }
            }
            DoTask(task_current_waypoint.Position);
        }
        void UpdateGeneralTask()
        {
            switch( generalTaskType )
            {
            case GeneralTaskTypes.WayMove:
                {
                    const float wayPointCheckDistance = 10;

                    float wayPointDistance = ( ControlledObject.Position -
                        generalTaskCurrentWayPoint.Position ).LengthFast();

                    if( wayPointDistance < wayPointCheckDistance )
                    {
                        //next way point or stop

                        int index = generalTaskWay.Points.IndexOf( generalTaskCurrentWayPoint );
                        index++;

                        if( index < generalTaskWay.Points.Count )
                        {
                            //next way point
                            generalTaskCurrentWayPoint = generalTaskWay.Points[ index ];
                        }
                        else
                        {
                            //task completed
                            DoGeneralTask( GeneralTaskTypes.None, null );
                        }
                    }

                    if( generalTaskCurrentWayPoint != null )
                        DoMoveTask( generalTaskCurrentWayPoint.Position );
                }
                break;

            case GeneralTaskTypes.Battle:
                {
                    Dynamic enemy = FindEnemy( ControlledObject.ViewRadius );
                    if( enemy != null )
                    {
                        //notify allies
                        NotifyAlliesOnEnemy( enemy.Position );

                        //Tank specific
                        Tank tank = ControlledObject as Tank;
                        if( tank != null )
                        {
                            Range range = tank.Type.OptimalAttackDistanceRange;
                            float distance = ( enemy.Position - ControlledObject.Position ).LengthFast();

                            bool needMove = false;

                            if( distance > range.Maximum )
                                needMove = true;

                            if( !needMove && attackTasks.Count != 0 )
                            {
                                //to check up a line of fire
                                bool existsDirectedWeapons = false;
                                foreach( AttackTask attackTask in attackTasks )
                                {
                                    if( IsWeaponDirectedToTarget( attackTask ) )
                                    {
                                        existsDirectedWeapons = true;
                                        break;
                                    }
                                }
                                if( !existsDirectedWeapons )
                                    needMove = true;
                            }

                            if( needMove )
                                DoMoveTask( enemy.Position );
                            else
                                ResetMoveTask();
                        }

                    }
                    else
                    {
                        if( moveTaskEnabled )
                        {
                            const float needDistance = 10;
                            float distance = ( moveTaskPosition - ControlledObject.Position ).LengthFast();
                            if( distance < needDistance )
                                ResetMoveTask();
                        }

                        if( !moveTaskEnabled )
                            DoGeneralTask( GeneralTaskTypes.None, null );
                    }
                }
                break;
            }

            //find enemies
            {
                if( generalTaskType != GeneralTaskTypes.Battle )
                {
                    Dynamic enemy = FindEnemy( ControlledObject.ViewRadius );
                    if( enemy != null )
                        DoGeneralTask( GeneralTaskTypes.Battle, null );
                }
            }
        }
        void DoGeneralTask( GeneralTaskTypes type, MapCurve way )
        {
            generalTaskType = type;
            generalTaskWay = way;
            generalTaskCurrentWayPoint = null;

            if( generalTaskWay != null )
                generalTaskCurrentWayPoint = generalTaskWay;

            //if( generalTaskType == GeneralTaskTypes.None )
            ResetMoveTask();
        }
        private void UpdateGeneralTask()
        {
            switch (generalTaskType)
            {
                case GeneralTaskTypes.WayMove:
                    {
                        if (generalTaskCurrentWayPoint == null)
                            return;
                        const float wayPointCheckDistance = 100;

                        float wayPointDistance = (ControlledObject.Position -
                            generalTaskCurrentWayPoint.Position).Length();

                        if (wayPointDistance < wayPointCheckDistance)
                        {
                            //next way point or stop

                            int index = generalTaskWay.Points.IndexOf(generalTaskCurrentWayPoint);
                            index++;

                            if (index < generalTaskWay.Points.Count)
                            {
                                //next way point
                                generalTaskCurrentWayPoint = generalTaskWay.Points[index];
                            }
                            else
                            {
                                //task completed
                                DoGeneralTask(GeneralTaskTypes.None, null);
                            }
                        }

                        if (generalTaskCurrentWayPoint != null)
                            DoMoveTask(generalTaskCurrentWayPoint.Position);
                    }
                    break;

                case GeneralTaskTypes.Battle:
                    {
                        Dynamic enemy = FindEnemy(ControlledObject.ViewRadius);
                        if (enemy != null)
                        {
                            //notify allies
                            NotifyAlliesOnEnemy(enemy.Position);

                            //Tank specific
                            Mech tank = ControlledObject as Mech;
                            if (tank != null)
                            {
                                Range range = tank.Type.OptimalAttackDistanceRange;
                                float distance = (enemy.Position - ControlledObject.Position).Length();

                                bool needMove = true;

                                if (distance > range.Maximum / 2f)
                                    needMove = true;
                                {
                                    if (!needMove && attackTasks.Count != 0)
                                    {
                                        //to check up a line of fire
                                        bool existsDirectedWeapons = false;
                                        foreach (AttackTask attackTask in attackTasks)
                                        {
                                            if (IsWeaponDirectedToTarget(attackTask))
                                            {
                                                existsDirectedWeapons = true;
                                                break;
                                            }
                                        }
                                        if (!existsDirectedWeapons)
                                            needMove = true;
                                    }
                                    if (generalTaskCurrentWayPoint != null)
                                        DoMoveTask(generalTaskCurrentWayPoint.Position);
                                    else if (needMove)
                                        DoMoveTask(enemy.Position);
                                    else
                                        ResetMoveTask();
                                }
                            }
                        }
                        else
                        {
                            if (moveTaskEnabled)
                            {
                                const float needDistance = 10;
                                float distance = (moveTaskPosition - ControlledObject.Position).Length();
                                if (distance < needDistance)
                                    ResetMoveTask();
                            }

                            if (!moveTaskEnabled)
                                DoGeneralTask(GeneralTaskTypes.None, null);
                        }
                    }
                    break;

                case GeneralTaskTypes.Leave:
                    {
                        Dynamic enemy = FindEnemy(ControlledObject.ViewRadius);
                        if (enemy != null)
                        {
                            //notify allies
                            //NotifyAlliesOnEnemy(enemy.Position);

                            //Tank specific
                            Mech tank = ControlledObject as Mech;
                            if (tank != null)
                            {
                                Range range = tank.Type.OptimalAttackDistanceRange;
                                float distance = (enemy.Position - ControlledObject.Position).Length();
                                distance -= tank.Type.OptimalAttackDistanceRange.Minimum;

                                if (tank.Health < 200 || tank.MechShutDown == true || tank.GetHeatLevel() >= tank.Type.AKunitHeatMax - Type.Ai_HeatLevelWarning)
                                {
                                    bool needMove = false;

                                    if (distance <= range.Minimum)
                                        needMove = true;

                                    //if (attackTasks.Count >= 0)
                                    //{
                                    //    //to check up a line of fire
                                    //    bool existsDirectedWeapons = false;
                                    //    foreach (AttackTask attackTask in attackTasks)
                                    //    {
                                    //        if (IsWeaponDirectedToTarget(attackTask))
                                    //        {
                                    //            existsDirectedWeapons = true;
                                    //            break;
                                    //        }
                                    //    }
                                    //    if (!existsDirectedWeapons)
                                    //        needMove = true;
                                    //}

                                    if (needMove)
                                    {
                                        Vec3 pos = moveTaskPosition + ControlledObject.Position;
                                        DoMoveTask(pos);
                                    }
                                    else
                                        ResetMoveTask();
                                }
                            }
                        }
                        else
                        {
                            if (moveTaskEnabled)
                            {
                                const float needDistance = 20;
                                float distance = (moveTaskPosition + ControlledObject.Position).Length();
                                if (distance < needDistance)
                                    ResetMoveTask();
                            }

                            if (!moveTaskEnabled)
                                DoGeneralTask(GeneralTaskTypes.Leave, null);
                        }
                    }
                    break;

                case GeneralTaskTypes.Patrol:
                    {
                        //follow a map curve here
                        Dynamic enemy = FindEnemy(ControlledObject.ViewRadius);
                        if (enemy != null)
                            DoGeneralTask(GeneralTaskTypes.Battle, null);
                        else
                            DoGeneralTask(GeneralTaskTypes.Patrol, null);

                        break;
                    }
                case GeneralTaskTypes.PrimaryTargets:
                    {
                        DoGeneralTask(GeneralTaskTypes.Battle, null);
                        break;
                    }
                case GeneralTaskTypes.SecondaryTargets:
                    {
                        DoGeneralTask(GeneralTaskTypes.Battle, null);
                        break;
                    }
            }

            //find enemies
            {
                if (generalTaskType != GeneralTaskTypes.Battle)
                {
                    Dynamic enemy = FindEnemy(ControlledObject.ViewRadius);
                    if (enemy != null)
                        DoGeneralTask(GeneralTaskTypes.Battle, null);
                    else
                        DoGeneralTask(GeneralTaskTypes.WayMove, null);
                }
            }
        }
Example #10
0
        private void DoGeneralTask(GeneralTaskTypes type, MapCurve way)
        {
            generalTaskType = type;
            generalTaskWay = way;
            generalTaskCurrentWayPoint = null;

            switch (generalTaskType)
            {
                case GeneralTaskTypes.Battle:
                case GeneralTaskTypes.EnemyFlag:
                case GeneralTaskTypes.Leave:
                case GeneralTaskTypes.None:
                case GeneralTaskTypes.Patrol:
                case GeneralTaskTypes.PrimaryTargets:
                case GeneralTaskTypes.SecondaryTargets:
                case GeneralTaskTypes.TeamFlag:
                case GeneralTaskTypes.WayMove:
                    {
                        if (generalTaskWay != null)
                            generalTaskCurrentWayPoint = generalTaskWay;
                        break;
                    }
            }
            if (generalTaskType == GeneralTaskTypes.None)
                ResetMoveTask();
        }
        private void UpdateGeneralTask()
        {
            switch (generalTaskType)
            {
            case GeneralTaskTypes.WayMove:
            {
                const float wayPointCheckDistance = 10;

                float wayPointDistance = (ControlledObject.Position -
                                          generalTaskCurrentWayPoint.Position).Length();

                if (wayPointDistance < wayPointCheckDistance)
                {
                    //next way point or stop

                    int index = generalTaskWay.Points.IndexOf(generalTaskCurrentWayPoint);
                    index++;

                    if (index < generalTaskWay.Points.Count)
                    {
                        //next way point
                        generalTaskCurrentWayPoint = generalTaskWay.Points[index];
                    }
                    else
                    {
                        //task completed
                        DoGeneralTask(GeneralTaskTypes.None, null);
                    }
                }

                if (generalTaskCurrentWayPoint != null)
                {
                    DoMoveTask(generalTaskCurrentWayPoint.Position);
                }
            }
            break;

            case GeneralTaskTypes.Battle:
            {
                Dynamic enemy = FindEnemy(ControlledObject.ViewRadius);
                if (enemy != null)
                {
                    //notify allies
                    NotifyAlliesOnEnemy(enemy.Position);

                    //Tank specific
                    Tank tank = ControlledObject as Tank;
                    if (tank != null)
                    {
                        Range range    = tank.Type.OptimalAttackDistanceRange;
                        float distance = (enemy.Position - ControlledObject.Position).Length();

                        bool needMove = false;

                        if (distance > range.Maximum)
                        {
                            needMove = true;
                        }

                        if (!needMove && attackTasks.Count != 0)
                        {
                            //to check up a line of fire
                            bool existsDirectedWeapons = false;
                            foreach (AttackTask attackTask in attackTasks)
                            {
                                if (IsWeaponDirectedToTarget(attackTask))
                                {
                                    existsDirectedWeapons = true;
                                    break;
                                }
                            }
                            if (!existsDirectedWeapons)
                            {
                                needMove = true;
                            }
                        }

                        if (needMove)
                        {
                            DoMoveTask(enemy.Position);
                        }
                        else
                        {
                            ResetMoveTask();
                        }
                    }
                }
                else
                {
                    if (moveTaskEnabled)
                    {
                        const float needDistance = 10;
                        float       distance     = (moveTaskPosition - ControlledObject.Position).Length();
                        if (distance < needDistance)
                        {
                            ResetMoveTask();
                        }
                    }

                    if (!moveTaskEnabled)
                    {
                        DoGeneralTask(GeneralTaskTypes.None, null);
                    }
                }
            }
            break;
            }

            //find enemies
            {
                if (generalTaskType != GeneralTaskTypes.Battle)
                {
                    Dynamic enemy = FindEnemy(ControlledObject.ViewRadius);
                    if (enemy != null)
                    {
                        DoGeneralTask(GeneralTaskTypes.Battle, null);
                    }
                }
            }
        }
Example #12
0
        private void UpdateGeneralTask()
        {
            const float wayPointCheckDistance = 10;

            float wayPointDistance = (this.Position -
                CurrentWayPoint.Position).LengthFast();

            if (wayPointDistance < wayPointCheckDistance)
            {
                //next way point or start again from the 1 point

                int index = TaskWay.Points.IndexOf(CurrentWayPoint);
                index++;

                if (index < TaskWay.Points.Count)
                {
                    //next way point
                    CurrentWayPoint = TaskWay.Points[index];
                }
                else
                {
                    CurrentWayPoint = TaskWay.Points[0];
                }
            }

            if (CurrentWayPoint != null)
                DoMoveTask(CurrentWayPoint.Position);
        }
Example #13
0
        private void DoGeneralTask(MapCurve way)
        {
            TaskWay = way;
            CurrentWayPoint = null;

            if (TaskWay != null && CurrentWayPoint == null)
            {
                CurrentWayPoint = TaskWay;
            }
            if (CurrentWayPoint != null)
            {
                firstWay = false;
            }
        }
        private void GetMapCameraCurvePoint(out MapCurvePoint point, float MapCameraCurvePointTime)
        {
            point = null;
            //MapCameraCurvePointTime = 0;
            MapCurve mapCurve = (MapCurve)Entities.Instance.GetByName("MM_Curve");
            //MapCameraCurvePoint curvepoint;

            //for(int i = 0; i < mapCurve.Points.Count; i++)
            foreach (MapCurvePoint curvepoint in mapCurve.Points)
            {
                //curvepoint = mapCurve.Points.

                if (curvepoint.Time >= mapCurve.GetCurveTimeRange().Minimum &&
                   curvepoint.Time >= mapCurve.GetCurveTimeRange().Maximum)
                {
                    point = curvepoint;
                    return;
                }
            }
        }
        private unsafe void UpdateGeometry()
        {
            DestroyGeometry();

            Curve positionCurve = GetPositionCurve();

            Curve radiusCurve = null;

            {
                bool existsSpecialRadius = false;
                foreach (MapCurvePoint point in Points)
                {
                    RenderableCurvePoint point2 = point as RenderableCurvePoint;
                    if (point2 != null && point2.OverrideRadius >= 0)
                    {
                        existsSpecialRadius = true;
                        break;
                    }
                }

                if (existsSpecialRadius)
                {
                    switch (radiusCurveType)
                    {
                    case RadiusCurveTypes.UniformCubicSpline:
                        radiusCurve = new UniformCubicSpline();
                        break;

                    case RadiusCurveTypes.Bezier:
                        radiusCurve = new BezierCurve();
                        break;

                    case RadiusCurveTypes.Line:
                        radiusCurve = new LineCurve();
                        break;
                    }

                    for (int n = 0; n < Points.Count; n++)
                    {
                        MapCurvePoint point = Points[n];

                        if (!point.Editor_IsExcludedFromWorld())
                        {
                            float rad = radius;
                            RenderableCurvePoint renderableCurvePoint = point as RenderableCurvePoint;
                            if (renderableCurvePoint != null && renderableCurvePoint.OverrideRadius >= 0)
                            {
                                rad = renderableCurvePoint.OverrideRadius;
                            }
                            radiusCurve.AddValue(point.Time, new Vec3(rad, 0, 0));
                        }
                    }
                }
            }

            //create mesh
            Vertex[] vertices = null;
            int[]    indices  = null;
            if (positionCurve != null && positionCurve.Values.Count > 1 && Points.Count >= 2)
            {
                Vec3 positionOffset = -Position;

                int steps       = (Points.Count - 1) * pathSteps + 1;
                int vertexCount = steps * (shapeSegments + 1);
                int indexCount  = (steps - 1) * shapeSegments * 2 * 3;

                vertices = new Vertex[vertexCount];
                indices  = new int[indexCount];

                //fill data
                {
                    int   currentVertex   = 0;
                    int   currentIndex    = 0;
                    float currentDistance = 0;
                    Vec3  lastPosition    = Vec3.Zero;
                    Quat  lastRot         = Quat.Identity;

                    for (int nStep = 0; nStep < steps; nStep++)
                    {
                        int startStepVertexIndex = currentVertex;

                        float coefficient = (float)nStep / (float)(steps - 1);
                        Vec3  pos         = CalculateCurvePointByCoefficient(coefficient) + positionOffset;

                        Quat rot;
                        {
                            Vec3 v = CalculateCurvePointByCoefficient(coefficient + .3f / (float)(steps - 1)) -
                                     CalculateCurvePointByCoefficient(coefficient);
                            if (v != Vec3.Zero)
                            {
                                rot = Quat.FromDirectionZAxisUp(v.GetNormalize());
                            }
                            else
                            {
                                rot = lastRot;
                            }
                        }

                        if (nStep != 0)
                        {
                            currentDistance += (pos - lastPosition).Length();
                        }

                        float rad;
                        if (radiusCurve != null)
                        {
                            Range range = new Range(radiusCurve.Times[0], radiusCurve.Times[radiusCurve.Times.Count - 1]);
                            float t     = range.Minimum + (range.Maximum - range.Minimum) * coefficient;
                            rad = radiusCurve.CalculateValueByTime(t).X;
                        }
                        else
                        {
                            rad = radius;
                        }

                        for (int nSegment = 0; nSegment < shapeSegments + 1; nSegment++)
                        {
                            float rotateCoefficient = ((float)nSegment / (float)(shapeSegments));
                            float angle             = rotateCoefficient * MathFunctions.PI * 2;
                            Vec3  p = pos + rot * new Vec3(0, MathFunctions.Cos(angle) * rad, MathFunctions.Sin(angle) * rad);

                            Vertex vertex = new Vertex();
                            vertex.position = p;
                            Vec3 pp = p - pos;
                            if (pp != Vec3.Zero)
                            {
                                vertex.normal = pp.GetNormalize();
                            }
                            else
                            {
                                vertex.normal = Vec3.XAxis;
                            }
                            //vertex.normal = ( p - pos ).GetNormalize();
                            vertex.texCoord           = new Vec2(currentDistance * textureCoordinatesTilesPerMeter, rotateCoefficient + .25f);
                            vertex.tangent            = new Vec4(rot.GetForward(), 1);
                            vertices[currentVertex++] = vertex;
                        }

                        if (nStep < steps - 1)
                        {
                            for (int nSegment = 0; nSegment < shapeSegments; nSegment++)
                            {
                                indices[currentIndex++] = startStepVertexIndex + nSegment;
                                indices[currentIndex++] = startStepVertexIndex + nSegment + 1;
                                indices[currentIndex++] = startStepVertexIndex + nSegment + 1 + shapeSegments + 1;
                                indices[currentIndex++] = startStepVertexIndex + nSegment + 1 + shapeSegments + 1;
                                indices[currentIndex++] = startStepVertexIndex + nSegment + shapeSegments + 1;
                                indices[currentIndex++] = startStepVertexIndex + nSegment;
                            }
                        }

                        lastPosition = pos;
                        lastRot      = rot;
                    }
                    if (currentVertex != vertexCount)
                    {
                        Log.Fatal("RenderableCurve: UpdateRenderingGeometry: currentVertex != vertexCount.");
                    }
                    if (currentIndex != indexCount)
                    {
                        Log.Fatal("RenderableCurve: UpdateRenderingGeometry: currentIndex != indexCount.");
                    }
                }

                if (vertices.Length != 0 && indices.Length != 0)
                {
                    //create mesh
                    string meshName = MeshManager.Instance.GetUniqueName(
                        string.Format("__RenderableCurve_{0}_{1}", Name, uniqueMeshIdentifier));
                    uniqueMeshIdentifier++;
                    //string meshName = MeshManager.Instance.GetUniqueName( string.Format( "__RenderableCurve_{0}", Name ) );
                    mesh = MeshManager.Instance.CreateManual(meshName);
                    SubMesh subMesh = mesh.CreateSubMesh();
                    subMesh.UseSharedVertices = false;

                    //init vertexData
                    VertexDeclaration declaration = subMesh.VertexData.VertexDeclaration;
                    declaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position);
                    declaration.AddElement(0, 12, VertexElementType.Float3, VertexElementSemantic.Normal);
                    declaration.AddElement(0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0);
                    declaration.AddElement(0, 32, VertexElementType.Float4, VertexElementSemantic.Tangent, 0);

                    fixed(Vertex *pVertices = vertices)
                    {
                        subMesh.VertexData = VertexData.CreateFromArray(declaration, (IntPtr)pVertices,
                                                                        vertices.Length * Marshal.SizeOf(typeof(Vertex)));
                    }

                    subMesh.IndexData = IndexData.CreateFromArray(indices, 0, indices.Length, false);

                    //set material
                    subMesh.MaterialName = materialName;

                    //set mesh gabarites
                    Bounds bounds = Bounds.Cleared;
                    foreach (Vertex vertex in vertices)
                    {
                        bounds.Add(vertex.position);
                    }
                    mesh.SetBoundsAndRadius(bounds, bounds.GetRadius());
                }
            }

            //create MeshObject, SceneNode
            if (mesh != null)
            {
                meshObject = SceneManager.Instance.CreateMeshObject(mesh.Name);
                if (meshObject != null)
                {
                    meshObject.SetMaterialNameForAllSubObjects(materialName);
                    meshObject.CastShadows = true;

                    sceneNode = new SceneNode();
                    sceneNode.Attach(meshObject);
                    //apply offset
                    sceneNode.Position = Position;
                    MapObject.AssociateSceneNodeWithMapObject(sceneNode, this);
                }
            }

            //create collision body
            if (mesh != null && collision)
            {
                Vec3[] positions = new Vec3[vertices.Length];
                for (int n = 0; n < vertices.Length; n++)
                {
                    positions[n] = vertices[n].position;
                }
                string meshPhysicsMeshName = PhysicsWorld.Instance.AddCustomMeshGeometry(positions, indices, null,
                                                                                         MeshShape.MeshTypes.TriangleMesh, 0, 0);

                collisionBody                   = PhysicsWorld.Instance.CreateBody();
                collisionBody.Static            = true;
                collisionBody._InternalUserData = this;
                collisionBody.Position          = Position;

                MeshShape shape = collisionBody.CreateMeshShape();
                shape.MeshName     = meshPhysicsMeshName;
                shape.MaterialName = CollisionMaterialName;
                shape.ContactGroup = (int)ContactGroup.Collision;
                //shape.VehicleDrivableSurface = collisionVehicleDrivableSurface;

                collisionBody.PushedToWorld = true;
            }

            needUpdate = false;
        }