Beispiel #1
0
        public RGatheredBall(List <RBall> balls, City dockCity, List <City> path)
        {
            state      = State.WaitingGathering;
            subBalls   = balls;
            goPath     = path;
            sourceCity = dockCity;


            position = GetRGBallPosition(dockCity, dockCity.CurrentFacing);

            float lineCount = (float)Math.Sqrt(balls.Count);
            float span      = (MathEx.PIf * 2) / lineCount;

            ballOffsets = new List <Vector3>(balls.Count);
            for (int i = 0; i < balls.Count; i++)
            {
                float row = (float)i / lineCount;
                float col = (float)Math.IEEERemainder(i, lineCount);

                float radLng = col * span;
                float radLat = (2 * row - lineCount) * span;

                Vector3    positionInGBall = PlanetEarth.GetPosition(radLng, radLat, GBallRadius);
                Quaternion oriInGBall      = Quaternion.RotationMatrix(PlanetEarth.GetOrientation(radLng, radLat));
                ballOffsets.Add(positionInGBall);
                balls[i].Gather(this, positionInGBall + position, oriInGBall);
            }

            throwSound = (Normal3DSoundObject)SoundManager.Instance.MakeSoundObjcet("throw", null, 1500);
            catchSound = (Normal3DSoundObject)SoundManager.Instance.MakeSoundObjcet("catch", null, 1500);
        }
Beispiel #2
0
        public override void Parse(GameConfigurationSection sect)
        {
            base.Parse(sect);

            Radius = sect.GetSingle("Radius");

            float radLng = MathEx.Degree2Radian(Longitude);
            float radLat = MathEx.Degree2Radian(Latitude);

            stdPosition = PlanetEarth.GetPosition(radLng, radLat, PlanetEarth.PlanetRadius);
        }
Beispiel #3
0
        public override void InitalizeGraphics(RenderSystem rs)
        {
            ForestInfo info;

            info.Latitude  = Latitude;
            info.Longitude = Longitude;
            info.Radius    = Radius;

            info.Amount = CurrentAmount;

            //info.Plants = TreeModelLibrary.Instance.Get(0);

            model = TreeBatchModelManager.Instance.CreateInstance(rs, info);

            model.Touch();

            Transformation = model.GetWeakResource().Transformation;
            BoundingSphere = model.GetWeakResource().BoundingVolume;

            sound          = SoundManager.Instance.MakeSoundObjcet("forest", null, BoundingSphere.Radius);
            sound.Position = BoundingSphere.Center;

            {
                float radLng = MathEx.Degree2Radian(Longitude);
                float radLat = MathEx.Degree2Radian(Latitude);

                float alt = TerrainData.Instance.QueryHeight(radLng, radLat);

                stdPosition = PlanetEarth.GetPosition(radLng, radLat, alt * TerrainMeshManager.PostHeightScale + PlanetEarth.PlanetRadius);

                stdTransform = PlanetEarth.GetOrientation(radLng, radLat);
                stdTransform.TranslationValue = stdPosition;


                selectionSphere.Center = stdPosition;
                selectionSphere.Radius = 200;
            }

            FileLocation fl = FileSystem.Instance.Locate("wooden_board_green.mesh", GameFileLocs.Model);

            board = new Model(ModelManager.Instance.CreateInstance(rs, fl));
            board.CurrentAnimation.Clear();
            board.CurrentAnimation.Add(
                new NoAnimaionPlayer(
                    Matrix.Translation(0, 0, 25) *
                    Matrix.Scaling(2.7f, 2.7f, 2.7f) *
                    Matrix.RotationX(-MathEx.PiOver2) *
                    Matrix.RotationY((-MathEx.PIf * 7.0f) / 8.0f)
                    ));
        }
Beispiel #4
0
        public override void Parse(GameConfigurationSection sect)
        {
            base.Parse(sect);

            modelName = sect["Model"];

            scale = sect.GetSingle("Radius", 1);

            rot = sect.GetSingle("Amount", 0);

            float radLng = MathEx.Degree2Radian(Longitude);
            float radLat = MathEx.Degree2Radian(Latitude);

            float alt = TerrainData.Instance.QueryHeight(radLng, radLat);

            Position    = PlanetEarth.GetPosition(radLng, radLat, PlanetEarth.PlanetRadius + alt * TerrainMeshManager.PostHeightScale);
            Orientation = PlanetEarth.GetOrientation(radLng, radLat);
        }
Beispiel #5
0
        /// <summary>
        ///  有两个Map的坐标计算采集车朝向
        ///  Calculate the orientation by the given 2 points in Map's coordinate,
        ///  which can be converted from long-lat by Map.GetMapCoord
        /// </summary>
        /// <param name="pa"></param>
        /// <param name="pb"></param>
        /// <returns></returns>
        Quaternion GetOrientation(Point pa, Point pb)
        {
            float alng;
            float alat;
            float blng;
            float blat;

            // 先得到两个点的经纬度
            // first convert the coord to long-lat
            Map.GetCoord(pa.X, pa.Y, out alng, out alat);
            Map.GetCoord(pb.X, pb.Y, out blng, out blat);

            // 法向
            // calculate the normal vector(up vector)
            Vector3 n = PlanetEarth.GetNormal(alng, alat);

            // 高度
            // elevation
            float   altA = map.GetHeight(alng, alat);
            Vector3 posA = PlanetEarth.GetPosition(alng, alat, altA + PlanetEarth.PlanetRadius);
            float   altB = map.GetHeight(blng, blat);
            Vector3 posB = PlanetEarth.GetPosition(blng, blat, altB + PlanetEarth.PlanetRadius);

            Vector3 dir = posB - posA;

            dir.Normalize();
            Vector3 bi = Vector3.Cross(n, dir);

            bi.Normalize();

            n = Vector3.Cross(dir, bi);

            // 采集车旋转World矩阵由向量基构建
            // constitute a final world matrix using these vectors
            Matrix result = Matrix.Identity;

            result.Right   = bi;
            result.Up      = n;
            result.Forward = -dir;
            return(Quaternion.RotationMatrix(result));
        }
Beispiel #6
0
        public OceanWaterTile(RenderSystem rs, OceanWaterDataManager manager, int @long, int lat)
            : base(false)
        {
            renderSystem = rs;

            PlanetEarth.TileCoord2CoordNew(@long, lat, out tileCol, out tileLat);

            material = new Material(rs);

            FileLocation             fl  = FileSystem.Instance.Locate("WaterNormal.tex", GameFileLocs.Nature);
            ResourceHandle <Texture> map = TextureManager.Instance.CreateInstance(fl);

            material.SetTexture(1, map);

            fl  = FileSystem.Instance.Locate("WaterDudv.tex", GameFileLocs.Nature);
            map = TextureManager.Instance.CreateInstance(fl);
            material.SetTexture(0, map);

            material.SetEffect(EffectManager.Instance.GetModelEffect(WaterEffectFactory.Name));
            material.IsTransparent = true;
            material.ZWriteEnabled = false;
            material.ZEnabled      = true;
            material.CullMode      = CullMode.CounterClockwise;
            material.PriorityHint  = RenderPriority.Third;

            data0 = manager.GetData(Lod0Size, tileLat);
            //data1 = manager.GetData(Lod1Size, tileLat);


            float radtc = MathEx.Degree2Radian(tileCol);
            float radtl = MathEx.Degree2Radian(tileLat);
            float rad5  = PlanetEarth.DefaultTileSpan * 0.5f;

            BoundingSphere.Center = PlanetEarth.GetPosition(radtc + rad5, radtl - rad5);
            BoundingSphere.Radius = PlanetEarth.GetTileHeight(rad5 * 2);

            Transformation = Matrix.RotationY(radtc);
        }
Beispiel #7
0
        protected override void UpdateLocation()
        {
            float radLong = MathEx.Degree2Radian(this.Longitude);
            float radLat  = MathEx.Degree2Radian(this.Latitude);

            float altitude = TerrainData.Instance.QueryHeight(radLong, radLat);

            IsInOcean = false;
            if (altitude < 0)
            {
                altitude  = 0;
                IsInOcean = true;
            }

            this.Position = PlanetEarth.GetPosition(radLong, radLat, PlanetEarth.PlanetRadius + TerrainMeshManager.PostHeightScale * altitude);

            this.Transformation = PlanetEarth.GetOrientation(radLong, radLat);
            //this.InvTransformation = Matrix.Invert(Transformation);

            this.Transformation.TranslationValue = this.Position; // TranslationValue = pos;

            BoundingSphere.Radius = RulesTable.CityRadius;
            BoundingSphere.Center = this.Position;
        }
Beispiel #8
0
        public override void Update(GameTime dt)
        {
            float ddt = (float)dt.ElapsedGameTimeSeconds;

            #region 装货卸货
            // Process the loading/unloading
            if (isLoading && exRes != null)
            {
                if (harvStorage < props.Storage)
                {
                    // 计算开矿倍数,保证能够完成卸货
                    // calculate the loading/unloading ratio, to ensure with this speed multiplier
                    // the harvester can finish the job in time.
                    float scale = props.Storage / (RulesTable.HarvLoadingSpeed * RulesTable.HarvLoadingTime);

                    harvStorage += exRes.Exploit(RulesTable.HarvLoadingSpeed * ddt * scale);
                }
                loadingTime -= ddt;

                // 开矿loadingTime时间之后,停止并引发事件
                // when the time runs out, stop to raise the event
                if (loadingTime < 0)
                {
                    isFullLoaded = harvStorage >= props.Storage;
                    isLoading    = false;
                    if (GotThere != null)
                    {
                        GotThere(this, EventArgs.Empty);
                    }
                }
            }

            //else
            //{
            //    isFullLoaded = true;
            //    loadingTime = 0;
            //    if (GotThere != null)
            //        GotThere(this, EventArgs.Empty);
            //}
            if (isUnloading)
            {
                // 计算开矿倍数,保证能够完成卸货
                // calculate the loading/unloading ratio, to ensure with this speed multiplier
                // the harvester can finish the job in time.
                float scale = props.Storage / (RulesTable.HarvLoadingSpeed * RulesTable.HarvLoadingTime);

                float change = RulesTable.HarvLoadingSpeed * ddt * scale;

                // 检查车上的存量是否足够
                // check if remaining storage is enough
                if (harvStorage - change > 0)
                {
                    // 足够时定量卸下
                    // unload all when enough
                    harvStorage -= change;
                    // 并且通知城市得到资源
                    // and tell the city the amount of resource obtained
                    parent.NotifyGotResource(change);
                }
                else
                {
                    // 不够时把剩下的都卸了
                    // otherwise, unload all the remains
                    parent.NotifyGotResource(harvStorage);
                    harvStorage = 0;
                }

                loadingTime -= ddt;

                // 一定时间后停止
                // when the time runs out, stop to raise the event
                if (loadingTime < 0)
                {
                    isUnloading = false;
                    if (GotHome != null)
                    {
                        GotHome(this, EventArgs.Empty);
                    }
                }
            }
            #endregion

            float altitude = map.GetHeight(longtitude, latitude);

            if (currentPath != null)
            {
                int nextNode = currentNode + 1;

                if (nextNode >= currentPath.NodeCount)
                {
                    #region 寻路完毕,状态转换
                    // when the path following is finished, by reaching the final node
                    // switch to new state
                    nextNode           = 0;
                    nodeMotionProgress = 0;

                    if (currentPath.RequiresPathFinding)
                    {
                        // continues path finding
                        Move(destX, destY);
                    }
                    else
                    {
                        // stop by setting null
                        currentPath = null;

                        if (movePurpose == MovePurpose.Gather)
                        {
                            isLoading   = true;
                            loadingTime = RulesTable.HarvLoadingTime;
                        }
                        else if (movePurpose == MovePurpose.Home)
                        {
                            isUnloading = true;
                            loadingTime = RulesTable.HarvLoadingTime;
                        }
                    }
                    #endregion
                }
                else
                {
                    #region 路径节点插值
                    // calculate the interpolation between 2 nodes


                    // 采集车在每两个节点之间移动都是一定过程
                    // 其位置/朝向是插值结果。差值参数为nodeMotionProgress
                    // The locomotion of harvester between 2 MoveNode is a process in time.
                    // Its position and orientation is the result of interpolation, where
                    // nodeMotionProgress is the interpolation amount.

                    Point cp = currentPath[currentNode];
                    Point np = currentPath[nextNode];

                    // 在一开始就尝试获取下一节点位置
                    // Check if the position in the next 2 MoveNodes need to be updated,
                    // as parameters to calculate translation
                    if (!stateUpdated)
                    {
                        if (isAdjustingDirection)
                        {
                            // 在调整方向时,车是位置不动的
                            // The car does not move when changing direction

                            Map.GetCoord(np.X, np.Y, out src.Longitude, out src.Latitude);

                            src.Alt = map.GetHeight(src.Longitude, src.Latitude);

                            target.Longitude = src.Longitude;
                            target.Latitude  = src.Latitude;
                            target.Alt       = src.Alt;
                        }
                        else
                        {
                            Map.GetCoord(cp.X, cp.Y, out src.Longitude, out src.Latitude);
                            Map.GetCoord(np.X, np.Y, out target.Longitude, out target.Latitude);

                            src.Alt    = map.GetHeight(src.Longitude, src.Latitude);
                            target.Alt = map.GetHeight(target.Longitude, target.Latitude);
                        }
                        stateUpdated = true;
                    }

                    // 在进行了一半之后开始获取下一节点朝向
                    // When the interpolation amount run over 0.5, update the
                    // information for orientation of the next 2 nodes, as parameters to calculate
                    // turning.
                    if (nodeMotionProgress > 0.5f && !rotUpdated)
                    {
                        if (isAdjustingDirection)
                        {
                            target.Ori = GetOrientation(cp, np);
                        }
                        else
                        {
                            if (nextNode < currentPath.NodeCount - 1)
                            {
                                src.Ori    = GetOrientation(cp, np);
                                target.Ori = GetOrientation(np, currentPath[nextNode + 1]);
                            }
                            else
                            {
                                target.Ori = GetOrientation(cp, np);
                                src.Ori    = target.Ori;
                            }
                        }
                        rotUpdated = true;
                    }

                    if (!isAdjustingDirection)
                    {
                        float x = MathEx.LinearInterpose(cp.X, np.X, nodeMotionProgress);
                        float y = MathEx.LinearInterpose(cp.Y, np.Y, nodeMotionProgress);

                        Map.GetCoord(x, y, out longtitude, out latitude);
                    }
                    altitude = MathEx.LinearInterpose(src.Alt, target.Alt, nodeMotionProgress);

                    #region 动画控制
                    // Animate by changing the index

                    // Car have a different look when on water
                    if (altitude < 0)
                    {
                        mdlIndex++;
                    }
                    else
                    {
                        mdlIndex--;
                    }

                    if (mdlIndex < 0)
                    {
                        mdlIndex = 0;
                    }
                    if (mdlIndex >= NumModels)
                    {
                        mdlIndex = NumModels - 1;
                    }

                    if (model != null)
                    {
                        if (parent.Owner != null)
                        {
                            if (parent.Type == CityType.Oil)
                            {
                                ModelL0 = model_bad[mdlIndex];
                            }
                            else
                            {
                                ModelL0 = model[mdlIndex];
                            }
                        }
                        else
                        {
                            ModelL0 = null;
                        }
                    }
                    #endregion

                    // 采集车不会潜水
                    // Keep the car not diving
                    if (altitude < 0)
                    {
                        altitude = 0;
                    }

                    // 球面插值,计算出朝向
                    // Spherical interpolation for direction
                    Orientation = Matrix.RotationQuaternion(
                        Quaternion.Slerp(src.Ori, target.Ori, nodeMotionProgress > 0.5f ? nodeMotionProgress - 0.5f : nodeMotionProgress + 0.5f));

                    if (isAdjustingDirection)
                    {
                        nodeMotionProgress += 0.5f * ddt;
                    }
                    else
                    {
                        // 挺进节点插值进度
                        // Progress the interpolation between 2 nodes
                        nodeMotionProgress += 0.05f * acceleration;
                    }

                    // 检查节点之间插值是否完成
                    // Check if the interpolation is done
                    if (nodeMotionProgress > 1)
                    {
                        nodeMotionProgress = 0;

                        if (isAdjustingDirection)
                        {
                            // 我们只允许调整方向一次,调整这次不会让车在节点上移动,currentNode不变
                            // We only allow adjust the direction once
                            isAdjustingDirection = false;
                        }
                        else
                        {
                            currentNode++;
                        }

                        rotUpdated   = false;
                        stateUpdated = false;
                    }
                    #endregion
                }

                #region 加速度计算
                // Calculate the acceleration
                if (currentPath != null)
                {
                    // 检查是否是最后一个节点了
                    // Check if this is the last node
                    if (nextNode == currentPath.NodeCount - 1)
                    {
                        // 开始减速
                        // Deceleration
                        acceleration -= ddt * 1.5f;
                        // 防止减速的过慢
                        // Set the minimum
                        if (acceleration < 0.33f)
                        {
                            acceleration = 0.33f;
                        }
                    }
                    else if (!isAdjustingDirection)
                    {
                        // 平时都是加速到最大为止
                        // otherwise, increase to full speed
                        acceleration += ddt * 1.5f;
                        if (acceleration > 1)
                        {
                            acceleration = 1;
                        }
                    }
                }
                #endregion
            }
            else
            {
                acceleration = 0;
            }


            //Orientation *= PlanetEarth.GetOrientation(longtitude, latitude);

            // 通过插值计算的经纬度得到坐标
            // The position is obtained by the interpolated long-lat coordinate
            Position = PlanetEarth.GetPosition(longtitude, latitude, PlanetEarth.PlanetRadius + altitude);
            base.Update(dt);



            BattleField field = map.Field;


            if (parent != null && parent.Owner != null && parent.Owner.Type == PlayerType.LocalHuman)
            {
                field.Fog.LightArea(longtitude,
                                    latitude, MathEx.Degree2Radian(5));
            }

            Visibility = field.Fog.GetVisibility(longtitude,
                                                 latitude);
            //if (IsSelected && IsInVisibleRange)
            //{
            //    IsSelected = false;

            //}
        }
Beispiel #9
0
        public OceanWaterData(RenderSystem rs, int size, float lat)
        {
            this.Size = size;

            geoData = new GeomentryData();

            ObjectFactory fac = rs.ObjectFactory;

            vtxDecl = fac.CreateVertexDeclaration(WaterVertex.Elements);

            int len         = size - 1;
            int vertexCount = size * size;

            vertexBuffer = fac.CreateVertexBuffer(vertexCount, vtxDecl, BufferUsage.Static);

            float rad10 = PlanetEarth.DefaultTileSpan;
            float radtl = MathEx.Degree2Radian(lat);

            #region 顶点数据
            WaterVertex[] vtxArray = new WaterVertex[vertexCount];

            float cellAngle = rad10 / (float)len;

            float invSize = 1 / (float)size;
            // i为经度方向
            for (int i = 0; i < size; i++)
            {
                // j为纬度方向
                for (int j = 0; j < size; j++)
                {
                    Vector3 pos = PlanetEarth.GetPosition(j * cellAngle, radtl - i * cellAngle);
                    pos.Normalize();
                    pos *= PlanetEarth.PlanetRadius;

                    int index = i * size + j;

                    vtxArray[index].Position    = pos;
                    vtxArray[index].NormalCoord = new Vector2(i * invSize, j * invSize); // = index;
                }
            }
            vertexBuffer.SetData <WaterVertex>(vtxArray);
            #endregion

            #region 索引数据
            int indexCount = MathEx.Sqr(len) * 2 * 3;

            int[] indexArray = new int[indexCount];
            indexBuffer = fac.CreateIndexBuffer(IndexBufferType.Bit32, indexCount, BufferUsage.WriteOnly);

            for (int i = 0, index = 0; i < len; i++)
            {
                for (int j = 0; j < len; j++)
                {
                    int x = i;
                    int y = j;

                    indexArray[index++] = y * size + x;
                    indexArray[index++] = y * size + (x + 1);
                    indexArray[index++] = (y + 1) * size + (x + 1);

                    indexArray[index++] = y * size + x;
                    indexArray[index++] = (y + 1) * size + (x + 1);
                    indexArray[index++] = (y + 1) * size + x;
                }
            }
            indexBuffer.SetData <int>(indexArray);
            #endregion

            #region 构造GeomentryData
            geoData = new GeomentryData();
            geoData.VertexDeclaration = vtxDecl;

            geoData.VertexSize   = WaterVertex.Size;
            geoData.VertexBuffer = vertexBuffer;
            geoData.IndexBuffer  = indexBuffer;
            geoData.PrimCount    = MathEx.Sqr(len) * 2;
            geoData.VertexCount  = MathEx.Sqr(size);

            geoData.PrimitiveType = RenderPrimitiveType.TriangleList;

            geoData.BaseVertex = 0;

            #endregion
        }
Beispiel #10
0
        public override void InitalizeGraphics(RenderSystem rs)
        {
            float radLng = MathEx.Degree2Radian(Longitude);
            float radLat = MathEx.Degree2Radian(Latitude);

            bool isOcean = false;

            float alt = TerrainData.Instance.QueryHeight(radLng, radLat);

            if (alt < 0)
            {
                alt     = 0;
                isOcean = true;
            }

            frameIdx = Randomizer.GetRandomInt(FrameCount - 1);

            float scale = Game.ObjectScale * 3.7f;// 2.2f;

            if (isOcean)
            {
                model = new Model[FrameCount];
                for (int i = 0; i < FrameCount; i++)
                {
                    FileLocation fl = FileSystem.Instance.Locate("oilderricksea" + i.ToString("D2") + ".mesh", GameFileLocs.Model);

                    model[i] = new Model(ModelManager.Instance.CreateInstance(rs, fl));
                    model[i].CurrentAnimation.Clear();
                    model[i].CurrentAnimation.Add(new NoAnimaionPlayer(
                                                      Matrix.Scaling(scale, scale, scale) * Matrix.Translation(0, 18, 0) * Matrix.RotationY(-MathEx.PiOver4)));
                }
            }
            else
            {
                model = new Model[FrameCount];
                for (int i = 0; i < FrameCount; i++)
                {
                    FileLocation fl = FileSystem.Instance.Locate("oilderrick" + i.ToString("D2") + ".mesh", GameFileLocs.Model);

                    model[i] = new Model(ModelManager.Instance.CreateInstance(rs, fl));
                    model[i].CurrentAnimation.Clear();
                    model[i].CurrentAnimation.Add(new NoAnimaionPlayer(
                                                      Matrix.Scaling(scale, scale, scale) * Matrix.RotationY(-MathEx.PiOver4)));
                }
            }



            Position = PlanetEarth.GetPosition(radLng, radLat, PlanetEarth.PlanetRadius + alt * TerrainMeshManager.PostHeightScale);
            BoundingSphere.Center = position;

            BoundingSphere.Radius = 200;
            Orientation           = PlanetEarth.GetOrientation(radLng, radLat);

            sound          = SoundManager.Instance.MakeSoundObjcet("oil", null, BoundingSphere.Radius * 8.0f / 3.0f);
            sound.Position = position;


            FileLocation fl2 = FileSystem.Instance.Locate("wooden_board_oil.mesh", GameFileLocs.Model);

            board = new Model(ModelManager.Instance.CreateInstance(rs, fl2));
            board.CurrentAnimation.Clear();
            board.CurrentAnimation.Add(
                new NoAnimaionPlayer(
                    Matrix.Translation(-50, 25, 23) *
                    Matrix.Scaling(2.7f, 2.7f, 2.7f) *
                    Matrix.RotationX(-MathEx.PiOver2) *
                    Matrix.RotationY((-MathEx.PIf * 7.0f) / 8.0f)
                    ));
        }