Пример #1
0
			public Expectation(Name expectedName, LeafIndex expectedLeafIndex)
			{
				Contract.Requires(expectedName != null);

				ExpectedName = expectedName;
				ExpectedLeafIndex = expectedLeafIndex;
			}
Пример #2
0
		public ParsedElement(NotationFormIndex notationOccurenceIndex, ParseParsedIndex parsingIndex, LeafIndex start, LeafIndex end)
		{
			this.NotationIndex = notationOccurenceIndex;
			this.ParseIndex = parsingIndex;
			this.Start = start;
			this.End = end;
		}
Пример #3
0
    private LeafIndex GetLeafIndex(Mesh mesh, BranchIndex fromBranchIndex, GameObjectInfo objectInfo)
    {
        LeafIndex index = new LeafIndex();

        /*
         * 存储信息:
         * 索引值和器官类型
         * 用于后续判断不同时期的两个器官索引是否为相同索引
         */
        index.Index    = GetIndexWithSameType(OrganType.Leaf, fromBranchIndex);
        index.LeafMesh = mesh;

        /*
         * 存储空间信息:
         * 半径、旋转方向
         * 用于后续绘制
         */
        index.Radius   = objectInfo.Radius;
        index.Rotation = objectInfo.Rotation;

        /*
         * 存储上下文信息:
         * 从属枝干
         */
        index.From = fromBranchIndex;

        /*
         * 病虫害信息:
         * 细胞纹理
         */
        index.CelluarTex = CellularTexMemory.GetInstance().GetCellularTex(0);

        return(index);
    }
Пример #4
0
    private void LeafMorphologicalInheritance()
    {
        OrganMorphologicalInheritance();    //基类中的数据继承

        LeafIndex curLeafIndex = CurIndex as LeafIndex;
        LeafIndex preLeafIndex = PreIndex as LeafIndex;

        curLeafIndex.Width               = preLeafIndex.Width;
        curLeafIndex.LeafArea            = preLeafIndex.LeafArea;
        curLeafIndex.LeafArea_Uninsected = preLeafIndex.LeafArea_Uninsected;

        curLeafIndex.LimitRatio          = preLeafIndex.LimitRatio;
        curLeafIndex.Texture_PreDay      = GameObjectOperation.GetTexture(preLeafIndex.Belong);
        curLeafIndex.MeshHashCode_PreDay = preLeafIndex.LeafMesh.GetHashCode();
    }
Пример #5
0
    /// <summary>
    /// 模拟天空直射
    /// </summary>
    /// <param name="SolarDayAngle_Rad">太阳日角</param>
    /// <param name="SolarAltitude_Deg">太阳高度角</param>
    /// <param name="SolarAzimuth_Deg">太阳方位角</param>
    /// <param name="StartHour">开始的时间</param>
    /// <param name="EndHour">结束时间</param>
    /// <param name="_Octree">八叉树</param>
    /// <param name="d">光线之间的间隔,即光线密度</param>
    public static void DirectionLightSimulation(double SolarDayAngle_Rad, double SolarAltitude_Deg, double SolarAzimuth_Deg, double StartHour, double EndHour, Octree _Octree, float d)
    {
        Light[] Lights = DirectLights(SolarDayAngle_Rad, SolarAltitude_Deg, SolarAzimuth_Deg, _Octree, d);  //获取所有直射光线

        foreach (Light _Light in Lights)
        {
            Triangle HitTriangle;
            if (!RayTracing.CollisionDection(_Light, _Octree, out HitTriangle))
            {
                continue;                                                                   //如果该光线没有与三角面片相交,则遍历下一条光线
            }
            if (HitTriangle.Type != OrganType.Leaf)
            {
                continue;                                           //如果相交三角面片不为叶子,则遍历下一条光线
            }
            LeafIndex _LeafIndex = HitTriangle.Index as LeafIndex;
            _LeafIndex.DirectionEnergy += _Light.Energy;            //累加叶子的直射能量
        }
    }
Пример #6
0
    /// <summary>
    /// 模拟天空散射
    /// </summary>
    /// <param name="SolarDayAngle_Deg">太阳日角</param>
    /// <param name="SolarAltitude_Deg">太阳高度角</param>
    /// <param name="StartHour">开始的时间</param>
    /// <param name="EndHour">结束的时间</param>
    /// <param name="_Octree">八叉树</param>
    /// <param name="LatitudeNum">纬度方向的剖分个数</param>
    /// <param name="LongtitudeNum">经度度方向的剖分个数</param>
    public static void ScatterLightSimulation(TreeModel treeModel, double SolarDayAngle_Rad, double SolarAltitude_Deg, double StartHour, double EndHour, Octree _Octree, int LatitudeNum, int LongtitudeNum)
    {
        Triangle[] TreeTriangles = GameObjectOperation.GetTreeTriangles(treeModel).ToArray();                              //获取所有的三角面片

        double _ScatterIrradiance = ScatterIrradiance(SolarDayAngle_Rad, SolarAltitude_Deg, _Octree.Root.Bounds.center.y); //总散射辐射度

        LightCastHemisphere LightHemisphere = null;

        for (int i = 0; i < TreeTriangles.Length; i++)
        {
            if (TreeTriangles[i].Type != OrganType.Leaf)
            {
                continue;                                           //非叶片,无需计算散射辐射
            }

            /*
             * 优化
             * 限定天穹半球的大小
             * 每次三角面片,天穹半球跟随三角面片移动,无需重新计算
             */
            if (LightHemisphere == null)
            {
                LightHemisphere = new LightCastHemisphere(TreeTriangles[i].Center, _Octree.Root.Bounds);
            }
            else
            {
                LightHemisphere.MoveTo(TreeTriangles[i].Center);
            }

            /*
             * 通过天穹半球计算出天空散射透过率
             * 该面片上的平均散射辐射度(W / m^2) = 天空散射透过率 * 总散射辐射度
             * 该面片上的总辐射度(W) = 平均散射辐射度 * 该面片的面积
             * 注意:因为存在透明的纹理,因此需要再得到整个叶片模型的散射能量的基础上,再乘以非透明的比例,才能得到真正的散射能量
             */
            LeafIndex _LeafIndex = TreeTriangles[i].Index as LeafIndex;

            _LeafIndex.ModelScatterEnergy += (float)(LightHemisphere.GetSkyTransmissivity(LongtitudeNum, LatitudeNum, TreeTriangles, i) * _ScatterIrradiance * TreeTriangles[i].Area());
        }
    }
Пример #7
0
    /// <summary>
    /// 获取一定时间内平均PAR值(umol/(s * m^2))
    /// </summary>
    /// <param name="leafArea">叶片面积</param>
    public static double PARRecption_Mean(TreeModel treeModel, out double leafArea)
    {
        List <OrganIndex> organIndexes = treeModel.OrganIndexes;

        double energy = 0;

        leafArea = 0;

        foreach (OrganIndex organIndex in organIndexes)
        {
            if (organIndex.Type != OrganType.Leaf)
            {
                continue;                                       //非叶片索引
            }
            LeafIndex leafIndex = organIndex as LeafIndex;
            energy   += leafIndex.TotalEnergy;  //辐射能量累加(单位 W)
            leafArea += leafIndex.LeafArea;     //叶面积累加(单位 ㎡)
        }

        double radiation = energy / leafArea; //辐照度(单位 W * m^-2)

        return(SolarSim.IrradianceToPPFD(radiation));
    }
Пример #8
0
		public NameBinding(Name name, LeafIndex indexOfMatched, NameInstance matchedNameInstance)
		{
			this.Index = indexOfMatched;
			this.Name = name;
			this.Instance = matchedNameInstance;
		}
Пример #9
0
 /// <summary>
 /// 获取一定时间内单个叶片的PAR值(umol/(s * m^2))
 /// </summary>
 public static double PARRecption(LeafIndex index)
 {
     return(SolarSim.IrradianceToPPFD(index.TotalEnergy / index.LeafArea));
 }
Пример #10
0
    private void CreateLeafModel(LeafIndex index, Vector3 position)
    {
        /*
         * 计算形态数据:长度和最大宽度
         * 用于后续生成GameObject
         */
        index.MorphologicalSim();

        GameObject leafModel = (GameObject)GameObject.Instantiate(index.LeafMesh.Instance); //模型实例化

        leafModel.name = index.LeafMesh.Name;
        leafModel.tag  = "Organ";
        SetTagInParent(leafModel.transform, "Organ");

        /*
         * 设置空间信息
         */
        leafModel.transform.position = position;
        RotationGameObject(leafModel, position, index.Rotation);

        /*
         * 养分
         */
        List <Material> materials = GameObjectOperation.GetMaterials(leafModel);

        switch (EnvironmentParams.NutrientType)
        {
        case LightResponseType.N_LACK:
            //SetIllnessColor(materials, MaizeParams.lackN_Color);
            break;

        case LightResponseType.P_LACK:
            SetIllnessColor(materials, MaizeParams.lackP_Color);
            break;

        case LightResponseType.K_LACK:
            SetIllnessColor(materials, MaizeParams.lackK_Color);
            break;
        }


        /*
         * 设置形态信息
         * 受病虫害影响后,叶面积变化较大
         * 而整体比例影响较小
         * 故采用未受到病虫害影响的叶面积计算比例
         */
        float scale = Mathf.Sqrt((float)(index.LeafArea_Uninsected / index.UniformLeafArea));

        leafModel.transform.localScale = Vector3.one * scale;

        /*
         * 设置父节点
         */
        leafModel.transform.SetParent(BranchModel.transform);

        /*
         * 信息补齐
         */
        index.Belong = leafModel;

        m_listOrganModels.Add(leafModel);
    }
Пример #11
0
    public void MorphologicalSim(double biomass, bool isClear = true, bool isSameGC = false)
    {
        DataCheck();    //数据检查

        /*
         * 包含枝干和器官的索引
         * 其每一个索引包含了后续生成GameObject所需的形态信息(旋转角度)以及
         * 生成形态信息所需的数据(生物量、年龄)
         */
        List <OrganIndex> indexes = GetIndexes(isClear, isSameGC);

        /*
         * 分配生物量给各个器官
         * 累积的生物量为后续形态模拟提供参考依据
         */
        FunctionSim.PhotosynthateAllocation(this, biomass, FunctionSim.GrowthPeriodJudgment(BranchIndexes, OrganIndexes));

        /*
         * 遍历每个Index
         * 计算形态数据
         * 根据形态数据绘制GameObject
         */
        int             curLevel      = 0;
        Vector3         curPosition   = Vector3.zero;
        Stack <Vector3> positionStack = new Stack <Vector3>();

        foreach (OrganIndex index in indexes)
        {
            switch (index.Type)
            {
            case OrganType.Branch:
                BranchIndex branchIndex = index as BranchIndex;

                if (branchIndex.Level > curLevel)
                {
                    positionStack.Push(curPosition);
                }
                else if (branchIndex.Level < curLevel)
                {
                    curPosition = positionStack.Pop();
                }

                curLevel    = branchIndex.Level;
                curPosition = RecordBranchModel(branchIndex, curPosition);

                break;

            case OrganType.Leaf:

                LeafIndex leafIndex = index as LeafIndex;
                CreateLeafModel(leafIndex, curPosition);

                break;

            case OrganType.Flower:

                MaleIndex maleIndex = index as MaleIndex;
                CreateFlowerModel(maleIndex, curPosition);

                break;

            case OrganType.Fruit:

                FemaleIndex femaleIndex = index as FemaleIndex;
                CreateFruitModel(femaleIndex, curPosition);

                break;
            }
        }

        CreateBranchModel();

        /*
         * 病虫害模拟
         * 测试
         */
        InsectSimulation();

        PostProcessing();
    }