예제 #1
0
        public void AddSegment(RoadTemplate template, MapObject start, MapObject end)
        {
            var startNode = GetOrCreateNode(start);
            var endNode   = GetOrCreateNode(end);

            var edge = new RoadTopologyEdge(
                template,
                startNode,
                start.RoadType,
                endNode,
                end.RoadType);

            Edges.Add(edge);

            startNode.Edges.Add(edge);
            endNode.Edges.Add(edge);
        }
예제 #2
0
파일: Road.cs 프로젝트: CyberSys/OpenSAGE
        internal Road(
            ContentManager contentManager,
            HeightMap heightMap,
            RoadTemplate template,
            Vector3 startPosition,
            Vector3 endPosition)
        {
            const float heightBias = 1f;
            const float createNewVerticesHeightDeltaThreshold = 0.002f;

            var distance              = Vector3.Distance(startPosition, endPosition);
            var direction             = Vector3.Normalize(endPosition - startPosition);
            var centerToEdgeDirection = Vector3.Cross(Vector3.UnitZ, direction);
            var up = Vector3.Cross(direction, centerToEdgeDirection);

            var halfWidth = template.RoadWidth / 2;

            var textureAtlasSplit = 1 / 3f;

            var vertices = new List <RoadVertex>();

            // Step along road segment in units of 10. If the delta between
            // (a) the straight line from previous point to finish and
            // (b) the actual height of the terrain at this point
            // is > a threshold, create extra vertices.
            // TODO: I don't know if this is the right algorithm.

            void AddVertexPair(in Vector3 position, float distanceAlongRoad)
            {
                var u = distanceAlongRoad / 50;

                var p0 = position - centerToEdgeDirection * halfWidth;

                p0.Z += heightBias;

                vertices.Add(new RoadVertex
                {
                    Position = p0,
                    Normal   = up,
                    UV       = new Vector2(u, 0)
                });

                var p1 = position + centerToEdgeDirection * halfWidth;

                p1.Z += heightBias;

                vertices.Add(new RoadVertex
                {
                    Position = p1,
                    Normal   = up,
                    UV       = new Vector2(u, textureAtlasSplit)
                });
            }

            AddVertexPair(startPosition, 0);

            var previousPoint         = startPosition;
            var previousPointDistance = 0;

            for (var currentDistance = 10; currentDistance < distance; currentDistance += 10)
            {
                var position           = startPosition + direction * currentDistance;
                var actualHeight       = heightMap.GetHeight(position.X, position.Y);
                var interpolatedHeight = MathUtility.Lerp(previousPoint.Z, endPosition.Z, (currentDistance - previousPointDistance) / distance);

                if (Math.Abs(actualHeight - interpolatedHeight) > createNewVerticesHeightDeltaThreshold)
                {
                    AddVertexPair(position, currentDistance);
                    previousPoint         = position;
                    previousPointDistance = currentDistance;
                }
            }

            // Add last chunk.
            AddVertexPair(endPosition, distance);

            _boundingBox = BoundingBox.CreateFromPoints(vertices.Select(x => x.Position));

            _vertexBuffer = AddDisposable(contentManager.GraphicsDevice.CreateStaticBuffer(
                                              vertices.ToArray(),
                                              BufferUsage.VertexBuffer));

            var indices = new List <ushort>();

            for (var i = 0; i < vertices.Count - 2; i += 2)
            {
                indices.Add((ushort)(i + 0));
                indices.Add((ushort)(i + 1));
                indices.Add((ushort)(i + 2));

                indices.Add((ushort)(i + 1));
                indices.Add((ushort)(i + 2));
                indices.Add((ushort)(i + 3));
            }

            _numIndices = (uint)indices.Count;

            _indexBuffer = AddDisposable(contentManager.GraphicsDevice.CreateStaticBuffer(
                                             indices.ToArray(),
                                             BufferUsage.IndexBuffer));

            _material = AddDisposable(new RoadMaterial(
                                          contentManager,
                                          contentManager.EffectLibrary.Road));

            var texture = contentManager.Load <Texture>(Path.Combine("Art", "Textures", template.Texture));

            _material.SetTexture(texture);
        }
예제 #3
0
파일: Road.cs 프로젝트: ybwsfl/OpenSAGE
 internal Road(
     ContentManager contentManager,
     HeightMap heightMap,
     RoadTemplate template,
     in Vector3 startPosition,
 internal Road(
     AssetLoadContext loadContext,
     HeightMap heightMap,
     RoadTemplate template,
     in Vector3 startPosition,