예제 #1
0
        /// <summary>
        /// Generates the lod mesh data.
        /// </summary>
        /// <param name="treeInfo">The tree information.</param>
        /// <returns>The mesh data.</returns>
        private static RenderGroup.MeshData GenerateLodMeshData(TreeInfo treeInfo)
        {
            // From game code at 2017-08-02.
            RenderGroup.VertexArrays vertexArrays = (RenderGroup.VertexArrays) 0;
            int vertexCount   = 0;
            int triangleCount = 0;
            int objectCount   = 0;

            TreeInstance.CalculateGroupData(ref vertexCount, ref triangleCount, ref objectCount, ref vertexArrays);
            RenderGroup.MeshData data1 = new RenderGroup.MeshData(vertexArrays, vertexCount, triangleCount);
            RenderGroup.MeshData data2 = new RenderGroup.MeshData(vertexArrays, vertexCount * 4, triangleCount * 4);
            RenderGroup.MeshData data3 = new RenderGroup.MeshData(vertexArrays, vertexCount * 8, triangleCount * 8);
            RenderGroup.MeshData data4 = new RenderGroup.MeshData(vertexArrays, vertexCount * 16, triangleCount * 16);
            Vector3 zero1               = Vector3.zero;
            Vector3 zero2               = Vector3.zero;
            float   maxRenderDistance   = 0.0f;
            float   maxInstanceDistance = 0.0f;
            //int vertexIndex1 = 0;
            //int triangleIndex1 = 0;
            //for (int index = 0; index < 1; ++index)
            //    TreeInstance.PopulateGroupData(treeInfo, new Vector3(0.0f, 0.0f, (float)index), 1f, 1f, ref vertexIndex1, ref triangleIndex1, Vector3.zero, data1, ref zero1, ref zero2, ref maxRenderDistance, ref maxInstanceDistance);
            //int vertexIndex2 = 0;
            //int triangleIndex2 = 0;
            //for (int index = 0; index < 4; ++index)
            //    TreeInstance.PopulateGroupData(treeInfo, new Vector3(0.0f, 0.0f, (float)index), 1f, 1f, ref vertexIndex2, ref triangleIndex2, Vector3.zero, data2, ref zero1, ref zero2, ref maxRenderDistance, ref maxInstanceDistance);
            //int vertexIndex3 = 0;
            //int triangleIndex3 = 0;
            //for (int index = 0; index < 8; ++index)
            //    TreeInstance.PopulateGroupData(treeInfo, new Vector3(0.0f, 0.0f, (float)index), 1f, 1f, ref vertexIndex3, ref triangleIndex3, Vector3.zero, data3, ref zero1, ref zero2, ref maxRenderDistance, ref maxInstanceDistance);
            int vertexIndex4   = 0;
            int triangleIndex4 = 0;

            for (int index = 0; index < 16; ++index)
            {
                TreeInstance.PopulateGroupData(treeInfo, new Vector3(0.0f, 0.0f, (float)index), 1f, 1f, ref vertexIndex4, ref triangleIndex4, Vector3.zero, data4, ref zero1, ref zero2, ref maxRenderDistance, ref maxInstanceDistance);
            }

            return(data4);
        }
예제 #2
0
        public void PopulateGroupData(
            ushort segmentID, uint laneID, NetInfo.Lane laneInfo, bool destroyed,
            NetNode.Flags startFlags, NetNode.Flags endFlags,
            float startAngle, float endAngle,
            bool invert, bool terrainHeight, int layer,
            ref int vertexIndex, ref int triangleIndex, Vector3 groupPosition, RenderGroup.MeshData data, ref Vector3 min, ref Vector3 max, ref float maxRenderDistance, ref float maxInstanceDistance, ref bool hasProps)
        {
            NetLaneProps laneProps = laneInfo.m_laneProps;

            if (laneProps?.m_props == null)
            {
                return;
            }
            bool backward = (laneInfo.m_finalDirection & NetInfo.Direction.Both) == NetInfo.Direction.Backward || (laneInfo.m_finalDirection & NetInfo.Direction.AvoidBoth) == NetInfo.Direction.AvoidForward;
            bool reverse  = backward != invert;

            if (backward)  //swap
            {
                NetNode.Flags flags = startFlags;
                startFlags = endFlags;
                endFlags   = flags;
            }
            int nProps = laneProps.m_props.Length;

            for (int i = 0; i < nProps; i++)
            {
                NetLaneProps.Prop prop = laneProps.m_props[i];
                if (!prop.CheckFlags(m_flags, startFlags, endFlags) || m_length < prop.m_minLength)
                {
                    continue;
                }
                int repeatCountTimes2 = 2;
                if (prop.m_repeatDistance > 1f)
                {
                    repeatCountTimes2 *= Mathf.Max(1, Mathf.RoundToInt(m_length / prop.m_repeatDistance));
                }
                float halfSegmentOffset = prop.m_segmentOffset * 0.5f;
                if (m_length != 0f)
                {
                    halfSegmentOffset = Mathf.Clamp(halfSegmentOffset + prop.m_position.z / m_length, -0.5f, 0.5f);
                }
                if (reverse)
                {
                    halfSegmentOffset = 0f - halfSegmentOffset;
                }
                PropInfo finalProp = prop.m_finalProp;
                if ((object)finalProp != null)
                {
                    hasProps = true;
                    if (finalProp.m_prefabDataLayer == layer || finalProp.m_effectLayer == layer)
                    {
                        Color      color = Color.white;
                        Randomizer r     = new Randomizer((int)laneID + i);
                        for (int j = 1; j <= repeatCountTimes2; j += 2)
                        {
                            if (r.Int32(100u) >= prop.m_probability)
                            {
                                continue;
                            }
                            float    t         = halfSegmentOffset + (float)j / (float)repeatCountTimes2;
                            PropInfo variation = finalProp.GetVariation(ref r);
                            float    scale     = variation.m_minScale + (float)r.Int32(10000u) * (variation.m_maxScale - variation.m_minScale) * 0.0001f;
                            if (prop.m_colorMode == NetLaneProps.ColorMode.Default)
                            {
                                color = variation.GetColor(ref r);
                            }
                            if (!variation.m_isDecal && destroyed)
                            {
                                continue;
                            }
                            Vector3 pos = m_bezier.Position(t);
                            Vector3 tan = m_bezier.Tangent(t);
                            if (!(tan != Vector3.zero))
                            {
                                continue;
                            }
                            if (reverse)
                            {
                                tan = -tan;
                            }
                            tan.y = 0f;
                            if (prop.m_position.x != 0f)
                            {
                                tan    = Vector3.Normalize(tan);
                                pos.x += tan.z * prop.m_position.x;
                                pos.z -= tan.x * prop.m_position.x;
                            }
                            float normalAngle = Mathf.Atan2(tan.x, 0f - tan.z);
                            if (prop.m_cornerAngle != 0f || prop.m_position.x != 0f)
                            {
                                float angleDiff = endAngle - startAngle;
                                if (angleDiff > Mathf.PI)
                                {
                                    angleDiff -= Mathf.PI * 2f;
                                }
                                if (angleDiff < -Mathf.PI)
                                {
                                    angleDiff += Mathf.PI * 2f;
                                }
                                var angle2 = startAngle + angleDiff * t - normalAngle;
                                if (angle2 > Mathf.PI)
                                {
                                    angle2 -= Mathf.PI * 2f;
                                }
                                if (angle2 < -Mathf.PI)
                                {
                                    angle2 += Mathf.PI * 2f;
                                }
                                normalAngle += angle2 * prop.m_cornerAngle;
                                if (angle2 != 0f && prop.m_position.x != 0f)
                                {
                                    float d = Mathf.Tan(angle2);
                                    pos.x += tan.x * d * prop.m_position.x;
                                    pos.z += tan.z * d * prop.m_position.x;
                                }
                            }
                            if (terrainHeight)
                            {
                                if (variation.m_requireWaterMap)
                                {
                                    pos.y = Singleton <TerrainManager> .instance.SampleRawHeightSmoothWithWater(pos, timeLerp : false, 0f);
                                }
                                else
                                {
                                    pos.y = Singleton <TerrainManager> .instance.SampleDetailHeight(pos);
                                }
                            }
                            pos.y += prop.m_position.y;
                            InstanceID id = default(InstanceID);
                            id.NetSegment = segmentID;
                            PropInstance.PopulateGroupData(angle: normalAngle + prop.m_angle * (Mathf.PI / 180f), info: variation, layer: layer, id: id, position: pos, scale: scale, color: color, vertexIndex: ref vertexIndex, triangleIndex: ref triangleIndex, groupPosition: groupPosition, data: data, min: ref min, max: ref max, maxRenderDistance: ref maxRenderDistance, maxInstanceDistance: ref maxInstanceDistance);
                        }
                    }
                }
                if (destroyed)
                {
                    continue;
                }
                TreeInfo finalTree = prop.m_finalTree;
                if ((object)finalTree == null)
                {
                    continue;
                }
                hasProps = true;
                if (finalTree.m_prefabDataLayer != layer)
                {
                    continue;
                }
                Randomizer r2 = new Randomizer((int)laneID + i);
                for (int k = 1; k <= repeatCountTimes2; k += 2)
                {
                    if (r2.Int32(100u) >= prop.m_probability)
                    {
                        continue;
                    }
                    float    t          = halfSegmentOffset + (float)k / (float)repeatCountTimes2;
                    TreeInfo variation2 = finalTree.GetVariation(ref r2);
                    float    scale2     = variation2.m_minScale + (float)r2.Int32(10000u) * (variation2.m_maxScale - variation2.m_minScale) * 0.0001f;
                    float    brightness = variation2.m_minBrightness + (float)r2.Int32(10000u) * (variation2.m_maxBrightness - variation2.m_minBrightness) * 0.0001f;
                    Vector3  vector3    = m_bezier.Position(t);
                    if (prop.m_position.x != 0f)
                    {
                        Vector3 vector4 = m_bezier.Tangent(t);
                        if (reverse)
                        {
                            vector4 = -vector4;
                        }
                        vector4.y  = 0f;
                        vector4    = Vector3.Normalize(vector4);
                        vector3.x += vector4.z * prop.m_position.x;
                        vector3.z -= vector4.x * prop.m_position.x;
                    }
                    if (terrainHeight)
                    {
                        vector3.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector3);
                    }
                    vector3.y += prop.m_position.y;
                    TreeInstance.PopulateGroupData(variation2, vector3, scale2, brightness, RenderManager.DefaultColorLocation, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance);
                }
            }
        }