示例#1
0
        public void Read(AssetReader reader)
        {
            Vertices.Read(reader);
            UV.Read(reader);
            if (IsReadBindPoses(reader.Version))
            {
                BindPoses.Read(reader);
            }
            Normals.Read(reader);
            Tangents.Read(reader);
            Weight.Read(reader);
            NormalSigns.Read(reader);
            TangentSigns.Read(reader);
            if (IsReadFloatColors(reader.Version))
            {
                FloatColors.Read(reader);
            }

            BoneIndices.Read(reader);
            Triangles.Read(reader);

            if (IsReadColors(reader.Version))
            {
                Colors.Read(reader);
            }
            if (IsReadUVInfo(reader.Version))
            {
                UVInfo = reader.ReadUInt32();
            }
        }
示例#2
0
        public void Write(AssetWriter writer)
        {
            Vertices.Write(writer);
            UV.Write(writer);
            if (HasBindPoses(writer.Version))
            {
                BindPoses.Write(writer);
            }

            Normals.Write(writer);
            Tangents.Write(writer);
            Weights.Write(writer);
            NormalSigns.Write(writer);
            TangentSigns.Write(writer);
            if (HasFloatColors(writer.Version))
            {
                FloatColors.Write(writer);
            }

            BoneIndices.Write(writer);
            Triangles.Write(writer);
            if (HasColors(writer.Version))
            {
                Colors.Write(writer);
            }
            if (HasUVInfo(writer.Version))
            {
                writer.Write(UVInfo);
            }
        }
示例#3
0
        public YAMLNode ExportYAML(IExportContainer container)
        {
            YAMLMappingNode node = new YAMLMappingNode();

            node.Add(VerticesName, Vertices.ExportYAML(container));
            node.Add(UVName, UV.ExportYAML(container));
            if (HasBindPoses(container.ExportVersion))
            {
                node.Add(BindPosesName, BindPoses.ExportYAML(container));
            }

            node.Add(NormalsName, Normals.ExportYAML(container));
            node.Add(TangentsName, Tangents.ExportYAML(container));
            node.Add(WeightsName, Weights.ExportYAML(container));
            node.Add(NormalSignsName, NormalSigns.ExportYAML(container));
            node.Add(TangentSignsName, TangentSigns.ExportYAML(container));
            if (HasFloatColors(container.ExportVersion))
            {
                node.Add(FloatColorsName, FloatColors.ExportYAML(container));
            }

            node.Add(BoneIndicesName, BoneIndices.ExportYAML(container));
            node.Add(TrianglesName, Triangles.ExportYAML(container));
            if (HasColors(container.ExportVersion))
            {
                node.Add(ColorsName, Colors.ExportYAML(container));
            }
            if (HasUVInfo(container.ExportVersion))
            {
                node.Add(UVInfoName, UVInfo);
            }
            return(node);
        }
示例#4
0
            public void AddBlendShapesToMesh(Mesh mesh)
            {
                Dictionary <string, BlendShape> map = new Dictionary <string, BlendShape>();

                foreach (var x in BlendShapes)
                {
                    BlendShape bs = null;
                    if (!map.TryGetValue(x.Name, out bs))
                    {
                        bs             = new BlendShape();
                        bs.Positions   = Positions.ToArray();
                        bs.Normals     = Normals.ToArray();
                        bs.Tangents    = Tangents.Select(y => (Vector3)y).ToArray();
                        bs.Name        = x.Name;
                        bs.FrameWeight = x.FrameWeight;
                        map.Add(x.Name, bs);
                    }

                    var j = x.VertexOffset;
                    for (int i = 0; i < x.Positions.Length; ++i, ++j)
                    {
                        bs.Positions[j] = x.Positions[i];
                        bs.Normals[j]   = x.Normals[i];
                        bs.Tangents[j]  = x.Tangents[i];
                    }
                }

                foreach (var kv in map)
                {
                    //Debug.LogFormat("AddBlendShapeFrame: {0}", kv.Key);
                    mesh.AddBlendShapeFrame(kv.Key, kv.Value.FrameWeight,
                                            kv.Value.Positions, kv.Value.Normals, kv.Value.Tangents);
                }
            }
    // Dubin curve distance
    public float Distance(DifferentialDriveState other)
    {
        Vector3 destination = other.position;
        float   angle       = Tangents.RotationAngle(orientation, destination - position);
        float   v           = maxVel;
        float   omega       = w;

        if (Mathf.Abs(angle) > 90)
        {
            angle = angle - 180 * Mathf.Sign(angle);
        }

        float d = Vector3.Distance(position, destination);

        //Debug.Log ("d: "+d);
        float absAngle = Mathf.Abs(angle);

        //Debug.Log ("phi: "+phi);
        float radius = (d / 2) / Mathf.Sin(absAngle * toRad);

        if (radius > r)
        {
            omega = v / radius;
        }
        return(Mathf.Abs(2 * (absAngle)) * toRad / omega);
    }
            public static Tangents Create(Vector3 from, Vector3 to, float circleRadius, CellMatrix matrix)
            {
                var t = new Tangents();

                t.Init(from, to, circleRadius, matrix);

                return(t);
            }
示例#7
0
            public static Tangents Create(Vector3 p1, Vector3 p3, float circleRadius)
            {
                var t = new Tangents();

                t.Init(p1, p3, circleRadius);

                return(t);
            }
示例#8
0
        public void RecalculateTangents()
        {
            if (HasUVs() == false)
            {
                UVs.Resize(Vertices.Count);
            }

            //partialy stolen from http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/

            int verticesNum = Vertices.Count;
            int indiciesNum = TriangleIndicies.Count;

            int[] counts = new int[verticesNum];

            Tangents.Clear();
            Tangents.Capacity = verticesNum;

            for (int i = 0; i < verticesNum; i++)
            {
                counts[i] = 0;
                Tangents.Add(Vector3.Zero);
            }

            for (int i = 0; i <= indiciesNum - 3; i += 3)
            {
                int ai = TriangleIndicies[i];
                int bi = TriangleIndicies[i + 1];
                int ci = TriangleIndicies[i + 2];

                if (ai < verticesNum && bi < verticesNum && ci < verticesNum)
                {
                    Vector3 av        = Vertices[ai];
                    Vector3 deltaPos1 = Vertices[bi] - av;
                    Vector3 deltaPos2 = Vertices[ci] - av;

                    Vector2 auv      = UVs[ai];
                    Vector2 deltaUV1 = UVs[bi] - auv;
                    Vector2 deltaUV2 = UVs[ci] - auv;

                    float   r = 1.0f / (deltaUV1.X * deltaUV2.Y - deltaUV1.Y * deltaUV2.X);
                    Vector3 t = (deltaPos1 * deltaUV2.Y - deltaPos2 * deltaUV1.Y) * r;

                    Tangents[ai] += t;
                    Tangents[bi] += t;
                    Tangents[ci] += t;

                    counts[ai]++;
                    counts[bi]++;
                    counts[ci]++;
                }
            }

            for (int i = 0; i < verticesNum; i++)
            {
                Tangents[i] /= counts[i];
            }
        }
示例#9
0
 public void Dispose()
 {
     Vertexes.Dispose();
     FaceIndexes.Dispose();
     TriangleOrder.Dispose();
     Normals.Dispose();
     Tangents.Dispose();
     Uvs.Dispose();
 }
示例#10
0
文件: Mesh.cs 项目: xorza/NetGL
        public void ToStream(BinaryWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }

            writer.Write(Vertices != null);
            if (Vertices != null)
            {
                Vertices.ToStream(writer.BaseStream);
            }

            writer.Write(Tangents != null);
            if (Tangents != null)
            {
                Tangents.ToStream(writer.BaseStream);
            }

            writer.Write(Colors != null);
            if (Colors != null)
            {
                Colors.ToStream(writer.BaseStream);
            }

            writer.Write(Normals != null);
            if (Normals != null)
            {
                Normals.ToStream(writer.BaseStream);
            }

            writer.Write(TexCoords != null);
            if (TexCoords != null)
            {
                TexCoords.ToStream(writer.BaseStream);
            }

            writer.Write(Indices != null);
            if (Indices != null)
            {
                Indices.ToStream(writer.BaseStream);
            }

            writer.Write((uint)Type);
            writer.Write((uint)DrawStyle);
            writer.Write((uint)FrontFace);
            writer.WriteNullableString(Name);

            var bounds = Bounds;

            writer.Write(bounds.Center);
            writer.Write(bounds.Size);
            writer.Write(bounds.Radius);
        }
示例#11
0
 /// <summary>
 /// Returns a value that indicates whether this instance and another <see cref="Mesh"/> are equal.
 /// </summary>
 /// <param name="other">The other <see cref="Mesh"/>.</param>
 /// <returns><see langword="true"/> if the two <see cref="Mesh"/> are equals; otherwise, <see langword="false"/>.</returns>
 public bool Equals(Mesh other) =>
 _hashcode == other._hashcode &&
 Material.Equals(other.Material) &&
 Vertices.SequenceEqual(other.Vertices) &&
 UVs.SequenceEqual(other.UVs) &&
 Normals.SequenceEqual(other.Normals) &&
 Faces.SequenceEqual(other.Faces) &&
 Tangents.SequenceEqual(other.Tangents) &&
 Bitangents.SequenceEqual(other.Bitangents) &&
 Colors.SequenceEqual(other.Colors) &&
 Bones.SequenceEqual(other.Bones);
 protected override void OnClearAllGeometryData()
 {
     base.OnClearAllGeometryData();
     Normals?.Clear();
     Normals?.TrimExcess();
     TextureCoordinates?.Clear();
     TextureCoordinates?.TrimExcess();
     Tangents?.Clear();
     Tangents?.TrimExcess();
     BiTangents?.Clear();
     BiTangents?.TrimExcess();
 }
示例#13
0
    // Creates a list of moves.
    /* Returns the shortest set of moves between two kinematic car states. */
    public Tuple <List <Move>, DynamicCarState> MovesTo(DynamicCarState other)
    {
        List <Move> moves = new List <Move> ();
        // create the move
        //float dr = Tangents.RotationAngle (orientation, other.position - this.position);
        float time = timeStep;
        // Sign of the acceleration determined by the difference in velocities
        // magnitude of acceleration is either maxAcc or the value needed to accelerate to reach the target speed.
        float acc = (speed < other.speed ? 1 : -1) * Mathf.Min(maxAcc, Mathf.Abs(this.speed - other.speed) / time);
        ////Debug.Log ("acc:" + acc);
        // The angle from current orientation to the destination is used to determine how much and in which direction the car should steer.
        float rotAngle = Tangents.RotationAngle(orientation, other.position - this.position);
        // The sign of the steering  * maximum or sufficient steering angle.
        float phi = Mathf.Sign(rotAngle) * Mathf.Min(Mathf.Abs(rotAngle), maxPhi);
        // turning radius determined and used to calculate the angular velocity
        float r = L / Mathf.Tan(Mathf.Abs(phi) * toRad);


        // Find the new state:
        DynamicCarState newState;
        float           endSpeed = speed + acc * time;
        float           angle    = ((speed + endSpeed) / (2 * r)) * time * toDeg;

        Vector3 carToCenter    = r * (Quaternion.Euler(0, 90 * Mathf.Sign(phi), 0) * orientation).normalized;
        Vector3 centerToCar    = -carToCenter;
        Vector3 center         = position + carToCenter;
        Vector3 newPosition    = Quaternion.Euler(0, angle * Mathf.Sign(phi), 0) * centerToCar + center;
        Vector3 newOrientation = Quaternion.Euler(0, angle * Mathf.Sign(phi), 0) * orientation;


        newState = new DynamicCarState(newPosition.x,
                                       newPosition.z,
                                       newOrientation,
                                       speed + acc * time);

        ////Debug.Log ("pos: " + newState.position);
        //Debug.Log ("Moving from: "+position+", or: "+orientation+"speed: "+speed+
//		           "\nTowards: "+other.position+", or: "+other.orientation+"speed: "+other.speed+
//		           "\nphi: " + phi + ", r: "+r+", angle: "+angle+", acc: "+acc+
//		           "\nnew state: "+newState.position + ", or: "+newState.orientation+", speed"+newState.speed);
        //		//Debug.Log (speed + acc * time);



        Move move = new DynamicCarMove(orientation, speed, acc, phi, r, newState, time);

        moves.Add(move);



        return(new Tuple <List <Move>, DynamicCarState> (moves, newState));
    }
示例#14
0
 public void Write(AssetsWriter writer)
 {
     Verticies.Write(writer);
     UV.Write(writer);
     Normals.Write(writer);
     Tangents.Write(writer);
     Weights.Write(writer);
     NormalSigns.Write(writer);
     TangentSigns.Write(writer);
     FloatColors.Write(writer);
     BoneIndicies.Write(writer);
     Triangles.Write(writer);
     writer.Write(UVInfo);
 }
示例#15
0
        public YAMLNode ExportYAML(IExportContainer container)
        {
            YAMLMappingNode node = new YAMLMappingNode();

            node.Add("m_Vertices", Vertices.ExportYAML(container));
            node.Add("m_UV", UV.ExportYAML(container));
            node.Add("m_Normals", Normals.ExportYAML(container));
            node.Add("m_Tangents", Tangents.ExportYAML(container));
            node.Add("m_Weights", Weight.ExportYAML(container));
            node.Add("m_NormalSigns", NormalSigns.ExportYAML(container));
            node.Add("m_TangentSigns", TangentSigns.ExportYAML(container));
            node.Add("m_FloatColors", IsReadFloatColors(container.Version) ? FloatColors.ExportYAML(container) : default(PackedFloatVector).ExportYAML(container));
            node.Add("m_BoneIndices", BoneIndices.ExportYAML(container));
            node.Add("m_Triangles", Triangles.ExportYAML(container));
            node.Add("m_UVInfo", UVInfo);
            return(node);
        }
示例#16
0
        public YAMLNode ExportYAML(IAssetsExporter exporter)
        {
#warning TODO: values acording to read version (current 2017.3.0f3)
            YAMLMappingNode node = new YAMLMappingNode();
            node.Add("m_Vertices", Vertices.ExportYAML(exporter));
            node.Add("m_UV", UV.ExportYAML(exporter));
            node.Add("m_Normals", Normals.ExportYAML(exporter));
            node.Add("m_Tangents", Tangents.ExportYAML(exporter));
            node.Add("m_Weights", Weight.ExportYAML(exporter));
            node.Add("m_NormalSigns", NormalSigns.ExportYAML(exporter));
            node.Add("m_TangentSigns", TangentSigns.ExportYAML(exporter));
            node.Add("m_FloatColors", IsReadFloatColors(exporter.Version) ? FloatColors.ExportYAML(exporter) : default(PackedFloatVector).ExportYAML(exporter));
            node.Add("m_BoneIndices", BoneIndices.ExportYAML(exporter));
            node.Add("m_Triangles", Triangles.ExportYAML(exporter));
            node.Add("m_UVInfo", UVInfo);
            return(node);
        }
示例#17
0
        public void Read(EndianStream stream)
        {
            if (IsReadMeshData)
            {
                Vertices.Read(stream);
                UV.Read(stream);
                if (IsReadBindPoses)
                {
                    BindPoses.Read(stream);
                }
                Normals.Read(stream);
                Tangents.Read(stream);
                Weight.Read(stream);
                NormalSigns.Read(stream);
                TangentSigns.Read(stream);

                if (IsReadFloatColors)
                {
                    FloatColors.Read(stream);
                }

                BoneIndices.Read(stream);
                Triangles.Read(stream);
            }

            if (IsReadPlainColors)
            {
                LocalAABB.Read(stream);
                m_plainColors = stream.ReadArray <Color>();
#warning TODO: todo what?
                m_collisionTriangles = stream.ReadByteArray();
                CollisionVertexCount = stream.ReadInt32();
            }
            else
            {
                if (IsReadCompressedColors)
                {
                    Colors.Read(stream);
                }
                else
                {
                    UVInfo = stream.ReadUInt32();
                }
            }
        }
示例#18
0
        public bool TryMerge(SubMesh other)
        {
            //  return false;

            if (MaterialID != other.MaterialID)
            {
                return(false);
            }

            int offset = Positions.Count;

            Positions.AddRange(other.Positions);
            Normals.AddRange(other.Normals);
            Tangents.AddRange(other.Tangents);
            TexCoords.AddRange(other.TexCoords);
            VertexColors.AddRange(other.VertexColors);

            foreach (int index in other.Indices)
            {
                Indices.Add(index + offset);
            }

            return(true);
        }
示例#19
0
        private void Dispose(bool disposing)
        {
            if (mDisposed)
            {
                return;
            }

            mDisposed = true;

            if (disposing)
            {
                Positions?.Dispose();
                Normals?.Dispose();
                Tangents?.Dispose();
                TexCoords0?.Dispose();
                TexCoords1?.Dispose();
                TexCoords2?.Dispose();
                TexCoords3?.Dispose();
                Colors0?.Dispose();
                Colors1?.Dispose();
            }

            GL.DeleteVertexArray(Id);
        }
示例#20
0
        public YAMLNode ExportYAML()
        {
#warning TODO: support different versions
            YAMLMappingNode node = new YAMLMappingNode();
            node.Add("m_Vertices", Vertices.ExportYAML());
            node.Add("m_UV", UV.ExportYAML());
            node.Add("m_Normals", Normals.ExportYAML());
            node.Add("m_Tangents", Tangents.ExportYAML());
            node.Add("m_Weights", Weight.ExportYAML());
            node.Add("m_NormalSigns", NormalSigns.ExportYAML());
            node.Add("m_TangentSigns", TangentSigns.ExportYAML());
            if (IsReadFloatColors)
            {
                node.Add("m_FloatColors", FloatColors.ExportYAML());
            }
            else
            {
                node.Add("m_FloatColors", PackedFloatVector.Empty.ExportYAML());
            }
            node.Add("m_BoneIndices", BoneIndices.ExportYAML());
            node.Add("m_Triangles", Triangles.ExportYAML());
            node.Add("m_UVInfo", UVInfo);
            return(node);
        }
示例#21
0
            public static Tangents Create(Vector3 p1, Vector3 p3, float circleRadius)
            {
                var t = new Tangents();
                t.Init(p1, p3, circleRadius);

                return t;
            }
示例#22
0
            public void Push(SkinnedMeshRenderer renderer)
            {
                var mesh = renderer.sharedMesh;

                if (mesh == null)
                {
                    Debug.LogWarningFormat("{0} has no mesh", renderer.name);
                    return;
                }

                Renderers.Add(renderer);

                var indexOffset     = Positions.Count;
                var boneIndexOffset = Bones.Count;

                Positions.AddRange(mesh.vertices);
                Normals.AddRange(mesh.normals);
                UV.AddRange(mesh.uv);
                Tangents.AddRange(mesh.tangents);

                if (mesh.vertexCount == mesh.boneWeights.Length)
                {
                    BoneWeights.AddRange(mesh.boneWeights.Select(x => AddBoneIndexOffset(x, boneIndexOffset)).ToArray());
                }
                else
                {
                    BoneWeights.AddRange(Enumerable.Range(0, mesh.vertexCount).Select(x => new BoneWeight()).ToArray());
                }

                BindPoses.AddRange(mesh.bindposes);
                Bones.AddRange(renderer.bones);

                for (int i = 0; i < mesh.subMeshCount; ++i)
                {
                    var indices = mesh.GetIndices(i).Select(x => x + indexOffset);
                    var mat     = renderer.sharedMaterials[i];
                    var sameMaterialSubMeshIndex = SubMeshes.FindIndex(x => ReferenceEquals(x.Material, mat));
                    if (sameMaterialSubMeshIndex >= 0)
                    {
                        SubMeshes[sameMaterialSubMeshIndex].Indices.AddRange(indices);
                    }
                    else
                    {
                        SubMeshes.Add(new SubMesh
                        {
                            Indices  = indices.ToList(),
                            Material = mat,
                        });
                    }
                }

                for (int i = 0; i < mesh.blendShapeCount; ++i)
                {
                    var positions = (Vector3[])mesh.vertices.Clone();
                    var normals   = (Vector3[])mesh.normals.Clone();
                    var tangents  = mesh.tangents.Select(x => (Vector3)x).ToArray();

                    mesh.GetBlendShapeFrameVertices(i, 0, positions, normals, tangents);
                    BlendShapes.Add(new BlendShape
                    {
                        VertexOffset = indexOffset,
                        FrameWeight  = mesh.GetBlendShapeFrameWeight(i, 0),
                        Name         = mesh.GetBlendShapeName(i),
                        Positions    = positions,
                        Normals      = normals,
                        Tangents     = tangents,
                    });
                }
            }
示例#23
0
        private static bool CanReducePath(IPositioned point1, IPositioned point3, IUnitProperties unitProps, CellMatrix matrix, ICellCostStrategy costStrategy)
        {
            Vector3 p1;
            Vector3 p3;

            //Assign the points so we start with the point with the lowest x-value to simplify things
            if (point1.position.x > point3.position.x)
            {
                p1 = point3.position;
                p3 = point1.position;
            }
            else
            {
                p1 = point1.position;
                p3 = point3.position;
            }

            var requesterRadius = unitProps.radius;
            var tan             = Tangents.Create(p1, p3, requesterRadius);

            var incZ     = tan.slopeDir;
            var cellSize = matrix.cellSize;
            var halfCell = cellSize / 2.0f;

            //Adjust the start and end cells to possibly include their immediate neighbour if the unit's radius crossed said boundary.
            var radiusAdjust = new Vector3(requesterRadius, 0.0f, requesterRadius * incZ);

            //Get the start and end cells, get the cost of the actual start and end, and then reassign the start and end with the above adjustment.
            var startCell = matrix.GetCell(p1, true);
            var startCost = costStrategy.GetCellCost(startCell, unitProps);

            startCell = matrix.GetCell(p1 - radiusAdjust, true);

            var endCell = matrix.GetCell(p3, true);
            var endCost = costStrategy.GetCellCost(endCell, unitProps);

            endCell = matrix.GetCell(p3 + radiusAdjust, true);

            //We want x to end up on cell boundaries, the first of which is this far from the first points position
            var xAdj = p1.x + (startCell.position.x - p1.x) + halfCell;

            //We want to adjust z so that we correctly count impacted cells, this adjusts z so it starts at the bottom boundary of the first cell (for purposes of calculation)
            var zAdj = p1.z - (halfCell + ((p1.z - startCell.position.z) * incZ));

            //The movement across the x-axis
            float deltaX = 0.0f;

            var cellMatrix = matrix.rawMatrix;
            int indexX     = 0;

            for (int x = startCell.matrixPosX; x <= endCell.matrixPosX; x++)
            {
                //So instead of just checking all cells in the bounding rect defined by the two cells p1 and p3,
                //we limit it to the cells immediately surrounding the proposed line (tangents), including enough cells that we ensure the unit will be able to pass through,
                //at the extreme routes between the two cells (i.e top corner to top corner and bottom corner to bottom corner
                int startZ;
                int endZ;

                //If the tangents are horizontal or vertical z range is obvious
                if (tan.isAxisAligned)
                {
                    startZ = startCell.matrixPosZ;
                    endZ   = endCell.matrixPosZ + incZ;
                }
                else
                {
                    if (indexX == 0)
                    {
                        startZ = startCell.matrixPosZ;
                    }
                    else
                    {
                        var startCellsPassed = Mathf.FloorToInt((tan.LowTangent(deltaX) - zAdj) / cellSize) * incZ;

                        startZ = LimitStart(
                            startCell.matrixPosZ + startCellsPassed,
                            startCell.matrixPosZ,
                            incZ);
                    }

                    //The movement this step will perform across the x-axis
                    deltaX = xAdj + (indexX * cellSize);

                    var endCellsIntercepted = Mathf.FloorToInt((tan.HighTangent(deltaX) - zAdj) / cellSize) * incZ;

                    endZ = LimitEnd(
                        startCell.matrixPosZ + endCellsIntercepted,
                        endCell.matrixPosZ,
                        incZ) + incZ;
                }

                indexX++;

                for (int z = startZ; z != endZ; z += incZ)
                {
                    var intermediary     = cellMatrix[x, z];
                    var intermediaryCost = costStrategy.GetCellCost(intermediary, unitProps);
                    if (!intermediary.isWalkableFrom(startCell, unitProps) || (startCost < intermediaryCost && endCost < intermediaryCost))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
示例#24
0
    // Obstructions, must check line and arc intersection
    override protected bool Obstructed(
        IEnumerable <Polygon> polys, Vector3 startPos)
    {
        Vector3 newPoint = this.PredictPosition(startPos);
        Vector2 sp       = new Vector2(startPos.x, startPos.z);
        Vector2 np       = new Vector2(newPoint.x, newPoint.z);

        // Length of the car
        float L = KinematicCarState.L;

        if (omega == 0.0f)                      // Check straight line intersection
        {
            Vector2 transVec = (np - sp).normalized * L;
            Vector2 midPoint = (sp + np) / 2;
            // TODO midPoint not necessary if you fix arc
            Edge e = new Edge(sp, np + transVec);                       // TODO check correctness
            foreach (Polygon p in polys)
            {
                if (p.Intersects(e) || p.IsInside(midPoint))
                {
                    return(true);
                }
            }
        }
        else                                            // Check arc intersection
        // Center of turning circle
        {
            Vector3 center = startPos + centerOff;
            Vector2 cp     = new Vector2(center.x, center.z);
            Vector2 cenToS = sp - cp;
            Vector2 cenToN = np - cp;

            // Angles of the arc
            float a1, a2;
            if (omega < 0)
            {
                a1 = Arc.Angle(Vector2.right, cenToS);
                a2 = Arc.Angle(Vector2.right, cenToN);
            }
            else
            {
                a1 = Arc.Angle(Vector2.right, cenToN);
                a2 = Arc.Angle(Vector2.right, cenToS);
            }

            /*Vector2 normal = Quaternion.Euler(0, 90, 0) * (sp - np);
             * float na = (a1 + a2) / 2;
             * Vector2 aaa2 = cp + normal * r;
             * Vector2 aaa3 = cp - normal * r;
             * float aaaa2 = Arc.Angle(Vector2.right, aaa2);
             * float aaaa3 = Arc.Angle(Vector2.right, aaa3);
             * Vector2 ffff = aaa2;
             * if (a1 < a2) {
             *      if (aaaa2 > a1 && aaaa2 < a2) {
             *              ffff = aaa2;
             *      }
             *      if (aaaa3 > a1 && aaaa3 < a2) {
             *              ffff = aaa3;
             *      }
             * } else {
             *      if (aaaa2 > a1 && aaaa2 < a2 && aaaa2 < 360 && aaaa2 > 0) {
             *              ffff = aaa2;
             *      }
             *      if (aaaa3 > a1 && aaaa3 < a2 && aaaa3 < 360 && aaaa3 > 0) {
             *              ffff = aaa3;
             *      }
             * }*/
            // Checking the front of the vehicle
            Vector3 transVec   = velocity.normalized * L;
            Vector3 cenToFront = -centerOff + transVec;
            float   frontR     = cenToFront.magnitude;
            float   diffAngle  = Tangents.RotationAngle(-centerOff, cenToFront);

            // Check if arc intersects with any of the polygons
            Arc arc = new Arc(cp, r, a1, a2);
            // TODO check correctness, if it is - or + diffAngle
            Arc frontArc = new Arc(cp, frontR, a1 - diffAngle, a2 - diffAngle);
            foreach (Polygon p in polys)
            {
                if (p.Intersects(arc) || p.Intersects(frontArc))
                {
                    return(true);
                }
            }
        }
        return(false);
    }
示例#25
0
        protected override YAMLMappingNode ExportYAMLRoot(IExportContainer container)
        {
            YAMLMappingNode node = base.ExportYAMLRoot(container);

            node.AddSerializedVersion(ToSerializedVersion(container.ExportVersion));
            if (HasLODData(container.ExportVersion))
            {
                node.Add(LODDataName, LODData.ExportYAML(container));
            }
            else
            {
                if (HasUse16bitIndices(container.ExportVersion))
                {
                    node.Add(Use16BitIndicesName, Use16BitIndices);
                }
                if (IsIndexBufferFirst(container.ExportVersion))
                {
                    node.Add(IndexBufferName, IndexBuffer.ExportYAML());
                }
                node.Add(SubMeshesName, SubMeshes.ExportYAML(container));
            }

            if (HasBlendShapes(container.ExportVersion))
            {
                if (HasBlendChannels(container.ExportVersion))
                {
                    node.Add(ShapesName, Shapes.ExportYAML(container));
                }
                else
                {
                    node.Add(ShapesName, BlendShapes.ExportYAML(container));
                    node.Add(ShapeVerticesName, ShapeVertices.ExportYAML(container));
                }
            }
            if (HasBindPose(container.ExportVersion))
            {
                if (IsBindPoseFirst(container.ExportVersion))
                {
                    node.Add(BindPoseName, BindPose.ExportYAML(container));
                }
            }
            if (HasBoneNameHashes(container.ExportVersion))
            {
                node.Add(BoneNameHashesName, BoneNameHashes.ExportYAML(true));
                node.Add(RootBoneNameHashName, RootBoneNameHash);
            }
            if (HasBonesAABB(container.ExportVersion))
            {
                node.Add(BonesAABBName, BonesAABB.ExportYAML(container));
                node.Add(VariableBoneCountWeightsName, VariableBoneCountWeights.ExportYAML(container));
            }

            if (HasMeshCompression(container.ExportVersion))
            {
                node.Add(MeshCompressionName, (byte)MeshCompression);
            }
            if (HasStreamCompression(container.ExportVersion))
            {
                node.Add(StreamCompressionName, StreamCompression);
            }
            if (HasIsReadable(container.ExportVersion))
            {
                node.Add(IsReadableName, IsReadable);
                node.Add(KeepVerticesName, KeepVertices);
                node.Add(KeepIndicesName, KeepIndices);
            }

            if (HasIndexFormat(container.ExportVersion))
            {
                node.Add(IndexFormatName, (int)IndexFormat);
            }

            if (!HasLODData(container.ExportVersion))
            {
                if (!IsIndexBufferFirst(container.ExportVersion))
                {
                    node.Add(IndexBufferName, IndexBuffer.ExportYAML());
                }
            }

            if (HasVertexData(container.ExportVersion))
            {
                if (!IsOnlyVertexData(container.ExportVersion))
                {
                    if (MeshCompression != MeshCompression.Off)
                    {
                        node.Add(VerticesName, Vertices.ExportYAML(container));
                    }
                }
            }
            else
            {
                node.Add(VerticesName, Vertices.ExportYAML(container));
            }

            if (HasSkin(container.ExportVersion))
            {
                node.Add(SkinName, Skin.ExportYAML(container));
            }
            if (HasBindPose(container.ExportVersion))
            {
                if (!IsBindPoseFirst(container.ExportVersion))
                {
                    node.Add(BindPoseName, BindPose.ExportYAML(container));
                }
            }

            if (HasVertexData(container.ExportVersion))
            {
                if (IsOnlyVertexData(container.ExportVersion))
                {
                    node.Add(VertexDataName, VertexData.ExportYAML(container));
                }
                else
                {
                    if (MeshCompression == MeshCompression.Off)
                    {
                        node.Add(VertexDataName, VertexData.ExportYAML(container));
                    }
                    else
                    {
                        node.Add(UVName, UV.ExportYAML(container));
                        node.Add(UV1Name, UV1.ExportYAML(container));
                        node.Add(TangentsName, Tangents.ExportYAML(container));
                        node.Add(NormalsName, Normals.ExportYAML(container));
                        node.Add(ColorsName, Colors.ExportYAML(container));
                    }
                }
            }
            else
            {
                node.Add(UVName, UV.ExportYAML(container));
                if (HasUV1(container.ExportVersion))
                {
                    node.Add(UV1Name, UV1.ExportYAML(container));
                }
                if (HasTangentSpace(container.ExportVersion))
                {
                    node.Add(TangentSpaceName, Tangents.ExportYAML(container));
                }
                else
                {
                    node.Add(TangentsName, Tangents.ExportYAML(container));
                    node.Add(NormalsName, Normals.ExportYAML(container));
                }
            }

            if (HasCompressedMesh(container.ExportVersion))
            {
                node.Add(CompressedMeshName, CompressedMesh.ExportYAML(container));
            }

            node.Add(LocalAABBName, LocalAABB.ExportYAML(container));
            if (!HasVertexData(container.ExportVersion))
            {
                node.Add(ColorsName, Colors.ExportYAML(container));
            }
            if (HasCollisionTriangles(container.ExportVersion))
            {
                node.Add(CollisionTrianglesName, CollisionTriangles.ExportYAML(true));
                node.Add(CollisionVertexCountName, CollisionVertexCount);
            }
            if (HasMeshUsageFlags(container.ExportVersion))
            {
                node.Add(MeshUsageFlagsName, MeshUsageFlags);
            }

            if (HasCollision(container.ExportVersion))
            {
                node.Add(BakedConvexCollisionMeshName, CollisionData.BakedConvexCollisionMesh.ExportYAML());
                node.Add(BakedTriangleCollisionMeshName, CollisionData.BakedTriangleCollisionMesh.ExportYAML());
            }
            if (HasMeshMetrics(container.ExportVersion))
            {
                node.Add(MeshMetricsName + "[0]", MeshMetrics[0]);
                node.Add(MeshMetricsName + "[1]", MeshMetrics[1]);
            }
            if (HasMeshOptimization(container.ExportVersion, container.ExportFlags))
            {
                if (IsMeshOptimizationFlags(container.ExportVersion))
                {
                    node.Add(MeshOptimizationFlagsName, (int)MeshOptimizationFlags);
                }
                else
                {
                    node.Add(MeshOptimizedName, MeshOptimized);
                }
            }
            if (HasStreamData(container.ExportVersion))
            {
                StreamingInfo streamData = new StreamingInfo(true);
                node.Add(StreamDataName, streamData.ExportYAML(container));
            }
            return(node);
        }
示例#26
0
        public override void Write(AssetWriter writer)
        {
            base.Write(writer);

            if (HasLODData(writer.Version))
            {
                LODData.Write(writer);
            }
            else
            {
                if (HasUse16bitIndices(writer.Version))
                {
                    writer.Write(Use16BitIndices);
                }
                if (IsIndexBufferFirst(writer.Version))
                {
                    IndexBuffer.Write(writer);
                    writer.AlignStream(AlignType.Align4);
                }
                SubMeshes.Write(writer);
            }

            if (HasBlendShapes(writer.Version))
            {
                if (HasBlendChannels(writer.Version))
                {
                    Shapes.Write(writer);
                }
                else
                {
                    BlendShapes.Write(writer);
                    writer.AlignStream(AlignType.Align4);
                    ShapeVertices.Write(writer);
                }
            }
            if (HasBindPose(writer.Version))
            {
                if (IsBindPoseFirst(writer.Version))
                {
                    BindPose.Write(writer);
                }
            }
            if (HasBoneNameHashes(writer.Version))
            {
                BoneNameHashes.Write(writer);
                writer.Write(RootBoneNameHash);
            }
            if (HasBonesAABB(writer.Version))
            {
                BonesAABB.Write(writer);
                VariableBoneCountWeights.Write(writer);
            }

            if (HasMeshCompression(writer.Version))
            {
                writer.Write((byte)MeshCompression);
            }
            if (HasStreamCompression(writer.Version))
            {
                writer.Write(StreamCompression);
            }
            if (HasIsReadable(writer.Version))
            {
                writer.Write(IsReadable);
                writer.Write(KeepVertices);
                writer.Write(KeepIndices);
            }
            if (IsAlignFlags(writer.Version))
            {
                writer.AlignStream(AlignType.Align4);
            }

            if (HasIndexFormat(writer.Version))
            {
                if (IsIndexFormatCondition(writer.Version))
                {
                    if (MeshCompression == MeshCompression.Off)
                    {
                        writer.Write((int)IndexFormat);
                    }
                }
                else
                {
                    writer.Write((int)IndexFormat);
                }
            }

            if (!HasLODData(writer.Version))
            {
                if (!IsIndexBufferFirst(writer.Version))
                {
                    IndexBuffer.Write(writer);
                    writer.AlignStream(AlignType.Align4);
                }
            }

            if (HasVertexData(writer.Version))
            {
                if (!IsOnlyVertexData(writer.Version))
                {
                    if (MeshCompression != MeshCompression.Off)
                    {
                        Vertices.Write(writer);
                    }
                }
            }
            else
            {
                Vertices.Write(writer);
            }

            if (HasSkin(writer.Version))
            {
                Skin.Write(writer);
            }
            if (HasBindPose(writer.Version))
            {
                if (!IsBindPoseFirst(writer.Version))
                {
                    BindPose.Write(writer);
                }
            }

            if (HasVertexData(writer.Version))
            {
                if (IsOnlyVertexData(writer.Version))
                {
                    VertexData.Write(writer);
                }
                else
                {
                    if (MeshCompression == MeshCompression.Off)
                    {
                        VertexData.Write(writer);
                    }
                    else
                    {
                        UV.Write(writer);
                        UV1.Write(writer);
                        Tangents.Write(writer);
                        Normals.Write(writer);
                        Colors.Write(writer);
                    }
                }
            }
            else
            {
                UV.Write(writer);
                if (HasUV1(writer.Version))
                {
                    UV1.Write(writer);
                }
                if (HasTangentSpace(writer.Version))
                {
                    TangentSpace.Write(writer);
                }
                else
                {
                    Tangents.Write(writer);
                    Normals.Write(writer);
                }
            }
            if (IsAlignVertex(writer.Version))
            {
                writer.AlignStream(AlignType.Align4);
            }

            if (HasCompressedMesh(writer.Version))
            {
                CompressedMesh.Write(writer);
            }

            LocalAABB.Write(writer);
            if (!HasVertexData(writer.Version))
            {
                Colors.Write(writer);
            }
            if (HasCollisionTriangles(writer.Version))
            {
                CollisionTriangles.Write(writer);
                writer.Write(CollisionVertexCount);
            }
            if (HasMeshUsageFlags(writer.Version))
            {
                writer.Write(MeshUsageFlags);
            }

            if (HasCollision(writer.Version))
            {
                CollisionData.Write(writer);
            }
            if (HasMeshMetrics(writer.Version))
            {
                writer.Write(MeshMetrics[0]);
                writer.Write(MeshMetrics[1]);
            }
#if UNIVERSAL
            if (HasMeshOptimization(writer.Version, writer.Flags))
            {
                if (IsMeshOptimizationFlags(writer.Version))
                {
                    writer.Write((int)MeshOptimizationFlags);
                }
                else
                {
                    writer.Write(MeshOptimized);
                }
            }
#endif
            if (HasStreamData(writer.Version))
            {
                writer.AlignStream(AlignType.Align4);
                StreamData.Write(writer);
            }
        }
示例#27
0
        public MeshIntegrationResult Integrate(MeshEnumerateOption onlyBlendShapeRenderers)
        {
            var mesh = new Mesh();

            if (Positions.Count > ushort.MaxValue)
            {
                Debug.LogFormat("exceed 65535 vertices: {0}", Positions.Count);
                mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            }

            mesh.vertices     = Positions.ToArray();
            mesh.normals      = Normals.ToArray();
            mesh.uv           = UV.ToArray();
            mesh.tangents     = Tangents.ToArray();
            mesh.boneWeights  = BoneWeights.ToArray();
            mesh.subMeshCount = SubMeshes.Count;
            for (var i = 0; i < SubMeshes.Count; ++i)
            {
                mesh.SetIndices(SubMeshes[i].Indices.ToArray(), MeshTopology.Triangles, i);
            }
            mesh.bindposes = BindPoses.ToArray();

            // blendshape
            switch (onlyBlendShapeRenderers)
            {
            case MeshEnumerateOption.OnlyWithBlendShape:
            {
                AddBlendShapesToMesh(mesh);
                mesh.name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME;
                break;
            }

            case MeshEnumerateOption.All:
            {
                AddBlendShapesToMesh(mesh);
                mesh.name = INTEGRATED_MESH_ALL_NAME;
                break;
            }

            case MeshEnumerateOption.OnlyWithoutBlendShape:
            {
                mesh.name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME;
                break;
            }
            }

            // meshName
            var meshNode = new GameObject();

            switch (onlyBlendShapeRenderers)
            {
            case MeshEnumerateOption.OnlyWithBlendShape:
            {
                meshNode.name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME;
                break;
            }

            case MeshEnumerateOption.OnlyWithoutBlendShape:
            {
                meshNode.name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME;
                break;
            }

            case MeshEnumerateOption.All:
            {
                meshNode.name = INTEGRATED_MESH_ALL_NAME;
                break;
            }
            }

            var integrated = meshNode.AddComponent <SkinnedMeshRenderer>();

            integrated.sharedMesh      = mesh;
            integrated.sharedMaterials = SubMeshes.Select(x => x.Material).ToArray();
            integrated.bones           = Bones.ToArray();
            Result.IntegratedRenderer  = integrated;
            Result.MeshMap.Integrated  = mesh;
            return(Result);
        }
示例#28
0
        public void Push(MeshRenderer renderer)
        {
            var meshFilter = renderer.GetComponent <MeshFilter>();

            if (meshFilter == null)
            {
                Debug.LogWarningFormat("{0} has no mesh filter", renderer.name);
                return;
            }
            var mesh = meshFilter.sharedMesh;

            if (mesh == null)
            {
                Debug.LogWarningFormat("{0} has no mesh", renderer.name);
                return;
            }
            Result.SourceMeshRenderers.Add(renderer);
            Result.MeshMap.Sources.Add(mesh);

            var indexOffset     = Positions.Count;
            var boneIndexOffset = Bones.Count;

            Positions.AddRange(mesh.vertices
                               .Select(x => renderer.transform.TransformPoint(x))
                               );
            Normals.AddRange(mesh.normals
                             .Select(x => renderer.transform.TransformVector(x))
                             );
            UV.AddRange(mesh.uv);
            Tangents.AddRange(mesh.tangents
                              .Select(t =>
            {
                var v = renderer.transform.TransformVector(t.x, t.y, t.z);
                return(new Vector4(v.x, v.y, v.z, t.w));
            })
                              );

            var self = renderer.transform;
            var bone = self.parent;

            if (bone == null)
            {
                Debug.LogWarningFormat("{0} is root gameobject.", self.name);
                return;
            }
            var bindpose = bone.worldToLocalMatrix;

            BoneWeights.AddRange(Enumerable.Range(0, mesh.vertices.Length)
                                 .Select(x => new BoneWeight()
            {
                boneIndex0 = Bones.Count,
                weight0    = 1,
            })
                                 );

            BindPoses.Add(bindpose);
            Bones.Add(bone);

            for (int i = 0; i < mesh.subMeshCount && i < renderer.sharedMaterials.Length; ++i)
            {
                var indices = mesh.GetIndices(i).Select(x => x + indexOffset);
                var mat     = renderer.sharedMaterials[i];
                var sameMaterialSubMeshIndex = SubMeshes.FindIndex(x => ReferenceEquals(x.Material, mat));
                if (sameMaterialSubMeshIndex >= 0)
                {
                    SubMeshes[sameMaterialSubMeshIndex].Indices.AddRange(indices);
                }
                else
                {
                    SubMeshes.Add(new SubMesh
                    {
                        Indices  = indices.ToList(),
                        Material = mat,
                    });
                }
            }
        }
示例#29
0
    // Creates a list of moves.
    /* Returns the shortest set of moves between two kinematic car states. */
    public Tuple <List <Move>, DifferentialDriveState> MovesTo(DifferentialDriveState other)
    {
        Vector3 destination = other.position;
        float   angle       = Tangents.RotationAngle(orientation, destination - position);
        float   v           = maxVel;
        float   omega       = w;
        //Debug.Log ("from: " + position + " to: " + destination);
        //Debug.Log ("Angle: "+angle);
        //Debug.Log ("orientation: "+orientation);

        //Debug.Log ("omega: "+omega);
        //Debug.Log ("v: "+v);

        Vector2 ori = orientation;
        int     directionOfSpeed = 1;

        if (Mathf.Abs(angle) > 90)
        {
            angle            = angle - 180 * Mathf.Sign(angle);
            ori              = -ori;
            directionOfSpeed = -1;
        }
        //Debug.Log ("new Angle: "+angle + ", neworientation: " + ori + ", direction of speed: "+directionOfSpeed);

        float d = Vector3.Distance(position, destination);

        //Debug.Log ("d: "+d);
        float absAngle = Mathf.Abs(angle);

        //Debug.Log ("phi: "+phi);
        float radius = (d / 2) / Mathf.Sin(absAngle * toRad);

        //Debug.Log ("radius: "+radius);

        if (radius > r)
        {
            omega = v / radius;
        }
        else
        {
            v = omega * radius;
        }
        //Debug.Log ("new omega: "+omega);
        //Debug.Log ("new v: "+v);


        //Debug.Log ("orientation: "+orientation + ", v*direction: " + (v * directionOfSpeed) + ", omega*signAngle: "+(omega * toDeg * Mathf.Sign (angle) )+"time: "+Mathf.Abs (2 * phi) * toRad / omega);
        List <Move> move = new List <Move>();

        move.Add(new KinematicCarMove(orientation,
                                      v * directionOfSpeed,
                                      omega * toDeg * Mathf.Sign(angle * directionOfSpeed),
                                      Mathf.Abs(2 * absAngle) * toRad / omega));

        Vector3 newOrientation = Quaternion.Euler(0, 2 * angle, 0) * orientation;
        //Debug.Log ("destination.x: "+destination.x + ", destination.z: " + destination.z + ", newOrientation: "+newOrientation);

        DifferentialDriveState newState = new DifferentialDriveState(destination.x,
                                                                     destination.z,
                                                                     newOrientation);

        return(new Tuple <List <Move>, DifferentialDriveState>(move, newState));
    }
示例#30
0
        /// <summary>
        /// Determines whether an unobstructed path exists between two points.
        /// </summary>
        /// <param name="from">The from point.</param>
        /// <param name="to">The to point.</param>
        /// <param name="unitProps">The unit properties to test against (Walkability).</param>
        /// <param name="matrix">The matrix where both <paramref name="from"/> and <paramref name="to"/> must be part of.</param>
        /// <param name="costStrategy">The cost strategy.</param>
        /// <returns><c>true</c> if an unobstructed path exists between the two points; otherwise <c>false</c>.</returns>
        public static bool CanReducePath(IPositioned from, IPositioned to, IUnitProperties unitProps, CellMatrix matrix, ICellCostStrategy costStrategy)
        {
            //The reference cell is always the from cell. The fact the points are swapped to simplify tangents does not affect this.
            var refCell = matrix.GetCell(from.position, false);

            Vector3 p1;
            Vector3 p2;

            //Assign the points so we start with the point with the lowest x-value to simplify things
            if (from.position.x > to.position.x)
            {
                p1 = to.position;
                p2 = from.position;
            }
            else
            {
                p1 = from.position;
                p2 = to.position;
            }

            var unitRadius = unitProps.radius;
            var tan        = Tangents.Create(p1, p2, unitRadius, matrix);

            var slopeDir = tan.slopeDir;
            var cellSize = matrix.cellSize;
            var halfCell = cellSize * 0.5f;

            //Get the start and end cells, get the cost of the actual start and end, and then reassign the start and end to accommodate for unit size.
            var startCell = matrix.GetCell(p1, false);
            var startCost = costStrategy.GetCellCost(startCell, unitProps);

            startCell = matrix.GetCell(new Vector3(p1.x - unitRadius, p1.y, p1.z), true);

            var endCell = matrix.GetCell(p2, false);
            var endCost = costStrategy.GetCellCost(endCell, unitProps);

            endCell = matrix.GetCell(new Vector3(p2.x + unitRadius, p2.y, p2.z), true);

            //The movement across the x-axis
            float minXCoord = (startCell.position.x - matrix.start.x) - halfCell;
            float maxXCoord = (startCell.position.x - matrix.start.x) + halfCell;

            int minZ;
            int maxZ;

            if (slopeDir < 0)
            {
                var distLowerCellBoundary = halfCell - (endCell.position.z - p2.z);
                var minOverlap            = Mathf.CeilToInt((unitRadius - distLowerCellBoundary) / cellSize);
                minZ = Math.Max(0, endCell.matrixPosZ - Math.Max(0, minOverlap));

                var distUpperCellBoundary = halfCell - (p1.z - startCell.position.z);
                var maxOverlap            = Mathf.CeilToInt((unitRadius - distUpperCellBoundary) / cellSize);
                maxZ = Math.Min(matrix.rows - 1, startCell.matrixPosZ + Math.Max(0, maxOverlap));
            }
            else
            {
                var distLowerCellBoundary = halfCell - (startCell.position.z - p1.z);
                var minOverlap            = Mathf.CeilToInt((unitRadius - distLowerCellBoundary) / cellSize);
                minZ = Math.Max(0, startCell.matrixPosZ - Math.Max(0, minOverlap));

                var distUpperCellBoundary = halfCell - (p2.z - endCell.position.z);
                var maxOverlap            = Mathf.CeilToInt((unitRadius - distUpperCellBoundary) / cellSize);
                maxZ = Math.Min(matrix.rows - 1, endCell.matrixPosZ + Math.Max(0, maxOverlap));
            }

            int  startX     = startCell.matrixPosX;
            int  endX       = endCell.matrixPosX;
            bool isVertical = tan.isVertical;
            var  cellMatrix = matrix.rawMatrix;

            for (int x = startX; x <= endX; x++)
            {
                int startZ;
                int endZ;

                if (isVertical)
                {
                    startZ = Math.Min(startCell.matrixPosZ, endCell.matrixPosZ);
                    endZ   = Math.Max(startCell.matrixPosZ, endCell.matrixPosZ);
                }
                else
                {
                    if (slopeDir < 0)
                    {
                        startZ = Math.Max((int)(tan.LowTangent(maxXCoord) / cellSize), minZ);
                        endZ   = Math.Min((int)(tan.HighTangent(minXCoord) / cellSize), maxZ);
                    }
                    else
                    {
                        startZ = Math.Max((int)(tan.LowTangent(minXCoord) / cellSize), minZ);
                        endZ   = Math.Min((int)(tan.HighTangent(maxXCoord) / cellSize), maxZ);
                    }
                }

                for (int z = startZ; z <= endZ; z++)
                {
                    var intermediary = cellMatrix[x, z];
                    if (!isVertical && tan.IsOutsideSecants(intermediary.position))
                    {
                        continue;
                    }

                    var intermediaryCost = costStrategy.GetCellCost(intermediary, unitProps);
                    if (!intermediary.IsWalkableFrom(refCell, unitProps) || (startCost < intermediaryCost || endCost < intermediaryCost))
                    {
                        return(false);
                    }
                }

                minXCoord = maxXCoord;
                maxXCoord = maxXCoord + cellSize;
            }

            return(true);
        }
示例#31
0
    /* Shortest dubin path between points on two seperate directed circles. */
    private List <Move> getShortestMovesBetween(Vector3 initial, Vector3 veli, Vector3 final, Vector3 velf, Vector3 rci, Vector3 rcf)
    {
        Vector3 center1 = initial + rci;
        Vector3 center2 = final + rcf;
        Vector3 di      = Vector3.Cross(veli, rci);
        Vector3 df      = Vector3.Cross(velf, rcf);

        /*If the circles intersect there exist no crossing tangents*/
        if (Vector3.Dot(di, df) < 1 && (center2 - center1).magnitude < 2 * r)
        {
            return(new List <Move>());
        }
        /*Find the tangentpoints */

        Vector3[] tangentPoints = (Vector3.Dot(di, df) > 1) ? Tangents.parallelTangentPoints(center1, center2, r)
                                                                                                                        : Tangents.intersectingTangentPoints(center1, center2, r);

        //Vector3 direction = center2 - center1;
        //Debug.Log ("direction: " + direction);
        Vector3 tangent = tangentPoints [1] - tangentPoints [0];
        //Debug.Log ("tangent: " + tangent);
        float sa, s, ea;

        Vector3 cross = Vector3.Cross(tangent, center1 - tangentPoints [0]);
        int     index = (Mathf.Sign(cross.y * di.y) > 0) ? 0 : 2;

        //Debug.Log ("index: " + index);
        //Debug.Log ("TP1: " + tangentPoints[index] + " TP2: " + tangentPoints [index+1]);


        sa = Tangents.RotationAngle(-rci, tangentPoints[index] - center1);
        ea = Tangents.RotationAngle(tangentPoints [index + 1] - center2, -rcf);
        // We want to move along the directionality of the circles
        //Debug.Log ("from: " + initial + " to: " + final);
        //Debug.Log ("sa: " + sa + "\n ea: " + ea + "\n  di: " + di.y + "\n df: "+df.y);
        if (Mathf.Sign(di.y * sa) < 0)
        {
            sa = Mathf.Sign(di.y) * (360 - Mathf.Abs(sa));
        }


        // We want to move along the directionality of the circles
        if (Mathf.Sign(df.y * ea) < 0)
        {
            ea = Mathf.Sign(df.y) * (360 - Mathf.Abs(ea));
        }


        Vector3 straight = tangentPoints [index + 1] - tangentPoints [index];

        s = (straight).magnitude;
        //float l = Mathf.Abs(sa) + s + Mathf.Abs(ea);
        //Debug.Log ("sa: " + sa + "\n ea: " + ea + "\n  di: " + di.y + "\n df: "+df.y + "\n s: " + s);
        List <Move> moves = new List <Move>();
        /*Never back up!*/

        float phi = maxPhi;
        float v   = maxVel;                     // Constant speed.  This will be altered when the path is finished.
        float W   = v * Mathf.Tan(Mathf.Abs(phi) * toRad) / L;

        //Debug.Log ("v: " + v + " , W: " + W + ", di: " + di.y );
        moves.Add(new KinematicCarMove(veli.normalized,
                                       v,
                                       W * toDeg * Mathf.Sign(di.y),
                                       Mathf.Abs(sa) * toRad / W));

        Vector3 orientation = Quaternion.Euler(0, sa, 0) * veli.normalized;

        moves.Add(new KinematicCarMove(orientation,
                                       v,
                                       0,
                                       s / Mathf.Abs(v)));
        moves.Add(new KinematicCarMove(orientation,
                                       v,
                                       W * toDeg * Mathf.Sign(df.y),
                                       Mathf.Abs(ea) * toRad / W));

        return(moves);

        /*
         * // the angles and paths for the two tangents
         * float sa1 = Tangents.RotationAngle( -rci, tangentPoints[0] - center1);
         * Vector3 straight1 = tangentPoints [1] - tangentPoints [0];
         * float s1 = (straight1).magnitude;
         * float ea1 = Tangents.RotationAngle ( tangentPoints [1] - center2, -rcf);
         * float l1 = Mathf.Abs(sa1) + s1 + Mathf.Abs(ea1);
         *
         * float sa2 = Tangents.RotationAngle(-rci, tangentPoints[2] - center1);
         * Vector3 straight2 = tangentPoints [3] - tangentPoints [2];
         * float s2 = (straight2).magnitude;
         * float ea2 = Tangents.RotationAngle (tangentPoints [3] - center2, -rcf);
         * float l2 = Mathf.Abs(sa2) + s2 + Mathf.Abs(ea2);
         *
         *
         * //Assign our path the shorter one
         * float sa, s, ea;
         * Vector3 straight;
         * if (l1 < l2) {
         *      sa = sa1; s = s1; ea = ea1; straight = straight1;
         * } else {
         *      sa = sa2; s = s2; ea = ea2;  straight = straight2;
         * }
         *
         * List<Move> moves = new List<Move>();
         * //negative speed: back up!  if the angle needed to make and the direction of the circle are of opposite sign the speed should be negative
         * float speed = maxVel * Mathf.Sign(sa) * Mathf.Sign(di.y);
         * moves.Add( new KinematicCarMove(veli.normalized, speed, w * toDeg * Mathf.Sign(di.y), Mathf.Abs(sa) * toRad/ w) );
         *
         * Vector3 orientation = Quaternion.Euler(0, sa, 0) * veli.normalized;
         * speed = maxVel * ((Vector3.Angle (orientation, straight) < 90) ? 1 : -1);  // If the orientation and straight path are opposite we need a negative velocity
         * moves.Add( new KinematicCarMove(orientation, speed, 0, s / Mathf.Abs(speed)) );
         *
         * speed = maxVel * Mathf.Sign(ea) * Mathf.Sign(df.y);
         * moves.Add( new KinematicCarMove(orientation, speed, w * toDeg * Mathf.Sign(df.y), Mathf.Abs(ea) * toRad / w) );
         *
         * return moves;*/
    }