示例#1
0
    /**
     * This function updates the spline mesh. It is called automatically once in a while, if updateMode isn't set to DontUpdate.
     */
    public void UpdateMesh( )
    {
        Setup( );

        //Reset the generated meshes
        if (BentMesh)
        {
            BentMesh.Clear( );
        }

        if (baseMesh == null || spline == null || segmentCount <= 0)
        {
            return;
        }


        //Gather model data
        Vector3[] verticesBase = baseMesh.vertices;
        Vector3[] normalsBase  = baseMesh.normals;
        Vector4[] tangentsBase = baseMesh.tangents;
        Vector2[] uvBase       = baseMesh.uv;

        int[] trianglesBase = baseMesh.triangles;


        //Allocate some memory for new mesh data
        Vector3[] verticesNew = new Vector3[verticesBase.Length * segmentCount];
        Vector3[] normalsNew  = new Vector3[normalsBase.Length * segmentCount];
        Vector4[] tangentsNew = new Vector4[tangentsBase.Length * segmentCount];
        Vector2[] uvNew       = new Vector2[uvBase.Length * segmentCount];

        int[] trianglesNew = new int[trianglesBase.Length * segmentCount];


        //Group front/rear vertices together
        List <int> verticesFront = new List <int>( );
        List <int> verticesBack  = new List <int>( );

        Vector3 centerFront = Vector3.zero;
        Vector3 centerBack  = Vector3.zero;

        for (int i = 0; i < verticesBase.Length; i++)
        {
            if (verticesBase[i].z > 0f)
            {
                verticesFront.Add(i);
                centerFront += verticesBase[i];
            }
            else if (verticesBase[i].z < 0f)
            {
                verticesBack.Add(i);
                centerBack += verticesBase[i];
            }
        }

        centerFront /= verticesFront.Count;
        centerBack  /= verticesBack.Count;


        if (splineSegment >= 0 && splineSegment < spline.SegmentCount)
        {
            SplineSegment currentSegment = spline.SplineSegments[splineSegment];

            int vIndex = 0;

            for (int segment = 0; segment < segmentCount; segment++)
            {
                float param0 = (float)segment / segmentCount;
                float param1 = (float)(segment + 1) / segmentCount;

                if (param1 == 1f)
                {
                    param1 -= 0.00001f;
                }

                param0 = currentSegment.ConvertSegmentToSplineParamter(param0);
                param1 = currentSegment.ConvertSegmentToSplineParamter(param1);

                CalculateBentMesh(ref vIndex, verticesFront, verticesBack, ref centerFront, ref centerBack, param0, param1,
                                  verticesBase, normalsBase, tangentsBase, uvBase, verticesNew, normalsNew, tangentsNew, uvNew);

                for (int i = 0; i < trianglesBase.Length; i++)
                {
                    trianglesNew[i + (segment * trianglesBase.Length)] = trianglesBase[i] + (verticesBase.Length * segment);
                }
            }

            BentMesh.vertices = verticesNew;
            BentMesh.uv       = uvNew;

            if (normalsBase.Length > 0)
            {
                BentMesh.normals = normalsNew;
            }

            if (tangentsBase.Length > 0)
            {
                BentMesh.tangents = tangentsNew;
            }

            BentMesh.triangles = trianglesNew;
        }
        else
        {
            int vIndex = 0;

            for (int segment = 0; segment < segmentCount; segment++)
            {
                float param0 = (float)segment / segmentCount;
                float param1 = (float)(segment + 1) / segmentCount;

                if (param1 == 1f)
                {
                    param1 -= 0.00001f;
                }

                CalculateBentMesh(ref vIndex, verticesFront, verticesBack, ref centerFront, ref centerBack, param0, param1,
                                  verticesBase, normalsBase, tangentsBase, uvBase, verticesNew, normalsNew, tangentsNew, uvNew);

                for (int i = 0; i < trianglesBase.Length; i++)
                {
                    trianglesNew[i + (segment * trianglesBase.Length)] = trianglesBase[i] + (verticesBase.Length * segment);
                }
            }

            BentMesh.vertices = verticesNew;
            BentMesh.uv       = uvNew;

            if (normalsBase.Length > 0)
            {
                BentMesh.normals = normalsNew;
            }

            if (tangentsBase.Length > 0)
            {
                BentMesh.tangents = tangentsNew;
            }

            BentMesh.triangles = trianglesNew;
        }
    }
示例#2
0
    private void UpdateMesh(Mesh dstMesh, int splineSegment, ref List <Vector3> lightProbePositions)
    {
        Vector2 probeExtents = new Vector2(baseMesh.bounds.extents.x + lightProbeExtrude.x, lightProbeExtrude.y);

        Vector3[] segmentProbePositions =
        {
            new Vector3(0,               probeExtents.y + lightProbeHeight * 0.5f, 0),
            new Vector3(probeExtents.x,  probeExtents.y,                           0),
            new Vector3(probeExtents.x,  probeExtents.y + lightProbeHeight,        0),
            new Vector3(-probeExtents.x, probeExtents.y,                           0),
            new Vector3(-probeExtents.x, probeExtents.y + lightProbeHeight, 0)
        };

        //Gather model data
        Vector3[] verticesBase = baseMesh.vertices;
        Vector3[] normalsBase  = baseMesh.normals;
        Vector4[] tangentsBase = baseMesh.tangents;
        Vector2[] uvBase       = baseMesh.uv;
        Vector2[] uvLightmap   = baseMesh.uv2;

        ArrayList allTrianglesBase = new ArrayList();

        for (int q = 0; q < baseMesh.subMeshCount; ++q)
        {
            allTrianglesBase.Add(baseMesh.GetTriangles(q));
        }

        var localSegmentCount = segmentCount / splineSegmentCount;

        //Allocate some memory for new mesh data
        Vector3[] verticesNew   = new Vector3[verticesBase.Length * localSegmentCount];
        Vector3[] normalsNew    = new Vector3[normalsBase.Length * localSegmentCount];
        Vector4[] tangentsNew   = new Vector4[tangentsBase.Length * localSegmentCount];
        Vector2[] uvNew         = new Vector2[uvBase.Length * localSegmentCount];
        Vector2[] lightmapUvNew = new Vector2[uvBase.Length * localSegmentCount];

        ArrayList allTrianglesNew = new ArrayList();

        for (int q = 0; q < baseMesh.subMeshCount; ++q)
        {
            allTrianglesNew.Add(new int[baseMesh.GetTriangles(q).Length *localSegmentCount]);
        }

        //Group front/rear vertices together
        List <int> verticesFront = new List <int>( );
        List <int> verticesBack  = new List <int>( );

        Vector3 centerFront = Vector3.zero;
        Vector3 centerBack  = Vector3.zero;
        Vector3 minCorner   = new Vector3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity);

        for (int i = 0; i < verticesBase.Length; i++)
        {
            if (verticesBase[i].z > 0f)
            {
                verticesFront.Add(i);
                centerFront += verticesBase[i];
            }
            else if (verticesBase[i].z < 0f)
            {
                verticesBack.Add(i);
                centerBack += verticesBase[i];
            }

            minCorner = Vector3.Min(minCorner, verticesBase[i]);

            verticesBase[i].x = verticesBase[i].x + xyOffset.x;
            verticesBase[i].y = verticesBase[i].y + xyOffset.y;
        }

        centerFront /= verticesFront.Count;
        centerBack  /= verticesBack.Count;


//		float meshAspect = (xyScale.x * baseMesh.bounds.size.x) / baseMesh.bounds.size.z;
//		Vector2 lightmapScale = new Vector2(
//			(baseMesh.bounds.size.x * xyScale.x),
//			spline.Length/(float)splineSegmentCount);
        //;;Debug.Log ("lightmapScale " + lightmapScale.x + "," + lightmapScale.y + " " + splineSegmentCount + " " + localSegmentCount + " " + baseMesh.bounds.size);


        int vIndex = 0;

        int boxDimension = (int)Mathf.Round(Mathf.Sqrt(localSegmentCount) + 0.5f);

        //;;Debug.Log ("boxDimension " + boxDimension);

        for (int segment = 0; segment < localSegmentCount; segment++)
        {
            float localParam0 = (float)segment / localSegmentCount;
            float localParam1 = (float)(segment + 1) / localSegmentCount;

            if (localParam1 == 1f)
            {
                localParam1 -= 0.00001f;
            }

            float splineParam0 = localParam0;
            float splineParam1 = localParam1;

            if (splitMesh && splineSegment < spline.SegmentCount)
            {
                SplineSegment currentSegment = spline.SplineSegments[splineSegment];

                splineParam0 = currentSegment.ConvertSegmentToSplineParamter(localParam0);
                splineParam1 = currentSegment.ConvertSegmentToSplineParamter(localParam1);
            }

            int onX = segment / boxDimension;
            //int onY = segment % boxDimension;
            //;;Debug.Log(onX + " " + onY);

            var columnStartingSegment = onX * boxDimension;
            var lightmapOffset        = new Vector2(
                onX,
                -Mathf.Max(0f, (float)columnStartingSegment / (float)localSegmentCount));

            CalculateBentMesh(ref vIndex, verticesFront, verticesBack, ref centerFront, ref centerBack,
                              splineParam0, splineParam1, localParam0, localParam1, new Vector2(1.0f / ((float)boxDimension), (float)(boxDimension - 1)), lightmapOffset,
                              verticesBase, normalsBase, tangentsBase, uvBase, uvLightmap,
                              verticesNew, normalsNew, tangentsNew, uvNew, lightmapUvNew);

            for (int q = 0; q < allTrianglesNew.Count; ++q)
            {
                int[] trianglesNew  = allTrianglesNew[q] as int[];
                int[] trianglesBase = allTrianglesBase[q] as int[];
                for (int i = 0; i < trianglesBase.Length; i++)
                {
                    trianglesNew[i + (segment * trianglesBase.Length)] = trianglesBase[i] + (verticesBase.Length * segment);
                }
            }
        }

        var localLightProbeSegmentCount = lightProbeSegmentCount / splineSegmentCount;

        for (int segment = 0; segment < localLightProbeSegmentCount + 1; segment++)
        {
            float param0 = (float)segment / localLightProbeSegmentCount;
            float paramC = ((float)segment + 0.5f) / localLightProbeSegmentCount;
            if (splitMesh && splineSegment < spline.SegmentCount)
            {
                SplineSegment currentSegment = spline.SplineSegments[splineSegment];
                param0 = currentSegment.ConvertSegmentToSplineParamter(param0);
                paramC = currentSegment.ConvertSegmentToSplineParamter(paramC);
            }

            Vector3    pos0 = spline.transform.InverseTransformPoint(spline.GetPositionOnSpline(param0));
            Quaternion rot0 = spline.GetOrientationOnSpline(param0) * Quaternion.Inverse(spline.transform.localRotation);
            Vector3    posC = spline.transform.InverseTransformPoint(spline.GetPositionOnSpline(paramC));
            Quaternion rotC = spline.GetOrientationOnSpline(paramC) * Quaternion.Inverse(spline.transform.localRotation);

            foreach (var probePos in segmentProbePositions)
            {
                lightProbePositions.Add(pos0 + rot0 * probePos);
            }
            if (segment != localLightProbeSegmentCount)
            {
                lightProbePositions.Add(posC + rotC * segmentProbePositions[0]);
            }
        }

        dstMesh.vertices = verticesNew;
        dstMesh.uv       = uvNew;
        dstMesh.uv2      = lightmapUvNew;

        if (normalsBase.Length > 0)
        {
            dstMesh.normals = normalsNew;
        }

        if (tangentsBase.Length > 0)
        {
            dstMesh.tangents = tangentsNew;
        }

        dstMesh.subMeshCount = allTrianglesNew.Count;
        for (int q = 0; q < allTrianglesNew.Count; ++q)
        {
            int[] trianglesNew = allTrianglesNew[q] as int[];
            dstMesh.SetTriangles(trianglesNew, q);
        }
    }