Пример #1
0
        public MeshVertex GetBent(MeshVertex vert)
        {
            var res = new MeshVertex(vert.position, vert.normal, vert.uv);

            // application of scale
            res.position = Vector3.Scale(res.position, new Vector3(0, scale.y, scale.x));

            // application of roll
            res.position = Quaternion.AngleAxis(roll, Vector3.right) * res.position;
            res.normal   = Quaternion.AngleAxis(roll, Vector3.right) * res.normal;

            // reset X value
            res.position.x = 0;

            // application of the rotation + location
            Quaternion q = Rotation * Quaternion.Euler(0, -90, 0);

            res.position = q * res.position + location;
            res.normal   = q * res.normal;
            return(res);
        }
Пример #2
0
        public void CreateMeshes()
        {
            if (null == spline || null == meshInfos || 0 == meshInfos.Length)
            {
                return;
            }

            UpdateSourceMeshes();
            UpdateDecisionParts();

            string generatedName     = "generated by " + GetType().Name;
            var    generatedTranform = transform.Find(generatedName);

            generated          = generatedTranform != null ? generatedTranform.gameObject : UOUtility.Create(generatedName, gameObject);
            generated.isStatic = false == updateInPlayMode;
            generated.layer    = gameObject.layer;

            var generatedChildren = generated.transform.Cast <Transform>().ToList();

            foreach (var child in generatedChildren)
            {
                if (null == child)
                {
                    continue;
                }

                var meshCollider = child.GetComponent <MeshCollider>();
                if (meshCollider)
                {
                    meshCollider.enabled = false;
                }
            }

            var meshChunkDict = new Dictionary <Material, List <MeshChunk> >();
            var sampleCache   = new Dictionary <float, CurveSample>();

            float offset = 0;

            for (int i = 0; i < decisionParts.Count; ++i)
            {
                int index = decisionParts[i];

                if (false == meshChunkDict.ContainsKey(meshInfos[index].material))
                {
                    meshChunkDict.Add(meshInfos[index].material, new List <MeshChunk>());
                }

                var meshChunkList = meshChunkDict[meshInfos[index].material];

                int vertexCount = meshInfos[index].mesh.vertices.Length;

                bool isReachedMaxVertices = 0 < meshChunkList.Count && PerChunkMaxVertices < (meshChunkList.Last().bentVertices.Count + vertexCount);
                bool isReachedMaxLength   = 0 < meshChunkList.Count && PerChunkMaxLength < meshChunkList.Last().length;
                if (0 == meshChunkList.Count || isReachedMaxVertices || isReachedMaxLength)
                {
                    meshChunkList.Add(new MeshChunk()
                    {
                        bentVertices = new List <MeshVertex>(vertexCount),
                        triangles    = new List <int>(vertexCount / 3),
                        uv           = new List <Vector2> [8],
                        length       = 0
                    });
                }

                var meshChunk = meshChunkList.Last();

                ref SourceMesh sourceMesh = ref sourceMeshes[index];

                meshChunk.triangles.AddRange(sourceMesh.Triangles.Select(idx => idx + meshChunk.bentVertices.Count));
                List <Vector2> UV = new List <Vector2>();
                for (int channel = 0; channel < 8; ++channel)
                {
                    UV.Clear();
                    sourceMesh.Mesh.GetUVs(channel, UV);
                    if (0 < UV.Count)
                    {
                        if (null == meshChunk.uv[channel])
                        {
                            meshChunk.uv[channel] = new List <Vector2>();
                        }
                        int fillCount = Mathf.Max(0, (meshChunk.bentVertices.Count - UV.Count) - meshChunk.uv[channel].Count);
                        if (0 < fillCount)
                        {
                            meshChunk.uv[channel].AddRange(Enumerable.Repeat(Vector2.zero, fillCount));
                        }
                        meshChunk.uv[channel].AddRange(UV);
                    }
                }

                foreach (var vertex in sourceMesh.Vertices)
                {
                    var vert = new MeshVertex(vertex.position, vertex.normal, vertex.uv);

                    vert.position.x *= partsScale;

                    float distance = vert.position.x - sourceMesh.MinX * partsScale + offset;

                    distance = Mathf.Clamp(distance, 0, spline.Length);

                    CurveSample sample;
                    if (false == sampleCache.TryGetValue(distance, out sample))
                    {
                        sample = spline.GetSampleAtDistance(distance);
                        if (heightSync)
                        {
                            var        sampleLocationWS = spline.transform.TransformPoint(sample.location);
                            RaycastHit hitInfo;
                            if (Physics.Raycast(sampleLocationWS + Vector3.up * heightSyncTraceRange, -Vector3.up, out hitInfo, heightSyncTraceRange * 2, heightSyncLayerMask))
                            {
                                var newSampleLocation = spline.transform.InverseTransformPoint(hitInfo.point);
                                var newSampleUp       = heightNormalSync ? spline.transform.InverseTransformDirection(hitInfo.normal) : sample.up;
                                sample = new CurveSample(newSampleLocation, sample.tangent, newSampleUp, sample.scale, sample.roll, sample.distanceInCurve, sample.timeInCurve, sample.curve);
                            }
                        }

                        sampleCache.Add(distance, sample);
                    }

                    MeshVertex bentVertex = sample.GetBent(vert);
                    meshChunk.bentVertices.Add(bentVertex);
                }

                offset           += sourceMeshes[index].Length * partsScale;
                meshChunk.length += sourceMeshes[index].Length * partsScale;
            }