[Ogre][地形][原创]基于OgreTerrain的地形实现

需要用到的外部图片资源:

在ogre调用时需要多用到的几个外部dll:

OgreTerrain_d.dll

需要添加头文件

#include "Ogre\Ogre.h"
#include "Ogre\OgreFileSystemLayer.h"
#include "Ogre\OgreTerrain.h"
#include "Ogre\OgreTerrainGroup.h"
#include "Ogre\OgreTerrainQuadTreeNode.h"
#include "Ogre\OgreTerrainMaterialGeneratorA.h"
#include "Ogre\OgreTerrainPaging.h"

定义类初始化需要的结构体

struct CrisTerrainInitStruct
{
CrisTerrainInitStruct():m_scenemanager(NULL),fMaxHoriz(1000),fMinHoriz(0),sMapFilename(""),sElevationFilename(""),fMapSize(TERRAIN_WORLD_SIZE)
{
fInputScale = fMaxHoriz - fMinHoriz;
}
SceneManager* m_scenemanager;
String sMapFilename; //地图卫星图片
String sElevationFilename;//高程图
Real fMinHoriz;//最低点
Real fMaxHoriz;//最高点
Real fMapSize;//地形边长
Real fInputScale; //地形高低差 对比像素的0~1 .可以不需要设置
//位置放在000点,
};

类的外部接口

void Init(CrisTerrainInitStruct* sInitData);

实现的一些重要步骤:

第一步  创建地形全局配置 TerrainGlobalOptions

mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
//TerrainGlobalOptions是一个类,定义了地形块的一些全局变量和默认值,需要的话我们可以改变他的变量参数,我们后面再做改变。

 第二步  创建地形分组Ogre::TerrainGroup

//实例化一个TerrainGroup对象

mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, m_sInitData->fMapSize);

第三步  配置地图块参数 configureTerrainDefaults

configureTerrainDefaults();

第四步  创建地形分块

//defineTerrain方法首先要指定该块地形在地形分组中的索引位置,然后第三个参数必须指定高度数据,用灰度图创建山地地形
for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)
for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)
defineTerrain(x, y, blankTerrain);

下面是我的代码:

头文件:

#pragma once
#define DebugTerrain
#include "Ogre\Ogre.h"
#include "Ogre\OgreFileSystemLayer.h"
#include "CrisConfig\CrisConfig.h"
#include "Ogre\OgreTerrain.h"
#include "Ogre\OgreTerrainGroup.h"
#include "Ogre\OgreTerrainQuadTreeNode.h"
#include "Ogre\OgreTerrainMaterialGeneratorA.h"
#include "Ogre\OgreTerrainPaging.h"

//分页多少
#define TERRAIN_PAGE_MIN_X 0
#define TERRAIN_PAGE_MIN_Y 0
#define TERRAIN_PAGE_MAX_X 0
#define TERRAIN_PAGE_MAX_Y 0

#define TERRAIN_FILE_PREFIX String("testTerrain")
#define TERRAIN_FILE_SUFFIX String("dat")
#define TERRAIN_WORLD_SIZE 1200.0f
#define TERRAIN_SIZE 513

using namespace Ogre;

struct CrisTerrainInitStruct
{
	CrisTerrainInitStruct():m_scenemanager(NULL),fMaxHoriz(1000),fMinHoriz(0),sMapFilename(""),sElevationFilename(""),fMapSize(TERRAIN_WORLD_SIZE)
	{
		fInputScale = fMaxHoriz - fMinHoriz;
	}
	SceneManager*	m_scenemanager;
	String			sMapFilename;	//地图卫星图片
	String			sElevationFilename;//高程图
	Real			fMinHoriz;//最低点
	Real			fMaxHoriz;//最高点
	Real			fMapSize;//地形边长
	Real			fInputScale;	//地形高低差 对比像素的0~1 .可以不需要设置
//位置放在000点,
};

class CrisTerrain
{
public:
	CrisTerrain();
	~CrisTerrain();
	void Init(CrisTerrainInitStruct*	sInitData);

	//void setTerrainImage(const Ogre::String& szCfgFilename = "terrain_texture.jpg");

protected:
	TerrainGlobalOptions* mTerrainGlobals;
	TerrainGroup* mTerrainGroup;
	TerrainPaging* mTerrainPaging;
	PageManager* mPageManager;

	void testOption();//为了小样例测试加载的,在大工程中可以直接不用
private:
	CrisTerrainInitStruct*	m_sInitData;
	void loadConfigFile(const Ogre::String& szCfgFilename = "");

	Ogre::String						m_szConfigFileName;
	CCrisConfigManager                  m_hConfigMgr;

	bool mFly;
	Real mFallVelocity;
	Real mBrushSizeTerrainSpace;

	Real mHeightUpdateCountDown;
	Real mHeightUpdateRate;
	Vector3 mTerrainPos;
	bool mTerrainsImported;

	SceneManager*			mSceneMgr;

	/** @brief 实例化地形 */
	void setupContent();
	/** @brief 实例化地形参数 */
	void configureTerrainDefaults();
	void initBlendMaps(Terrain* terrain);
	void defineTerrain(long x, long y, bool flat = false);
	void getTerrainImage(bool flipX, bool flipY, Image& img);

};

  实现文件:

#include "Terrain.h"

CrisTerrain::CrisTerrain(): mTerrainGroup(0)
	, mTerrainPaging(0)
	, mPageManager(0)
	, mFallVelocity(0)
	, mBrushSizeTerrainSpace(0.02)
	, mHeightUpdateCountDown(0)
	, mTerrainPos(0,0,0)
	, mTerrainsImported(false)
{

}

CrisTerrain::~CrisTerrain()
{

}

void CrisTerrain::Init(CrisTerrainInitStruct*	sInitData)
{
	mSceneMgr = sInitData->m_scenemanager;
	m_sInitData = sInitData;
	setupContent();
	//loadConfigFile("terrain.cfg");
}

void CrisTerrain::loadConfigFile(const String& szFilename)
{
	if(!szFilename.empty())
		m_szConfigFileName = szFilename;
	else
		return;

	//m_hConfigMgr.LoadFromResourceSystem(m_szConfigFileName);
	//String worldTexture = m_hConfigMgr.GetValueString("Ter", "WorldTexture", "testter.jpg");
	//OutputDebugString(worldTexture.c_str());

}

//void CrisTerrain::setTerrainImage(const Ogre::String& szCfgFilename)
//{
//	Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
//	defaultimp.terrainSize = TERRAIN_SIZE;//不太了解,调试中,这个值越小,地图边缘锯齿现象越严重,太小的话,运行起来程序会跑死、出错
//	defaultimp.worldSize = m_sInitData->fMapSize;//假设为a,那么地图大小为 a x a
//	defaultimp.inputScale = 60;//决定地图最大落差(高度),即位图中白色和黑色部分的高度差
//	defaultimp.minBatchSize = 33;
//	defaultimp.maxBatchSize = 65;
//	// textures
//	defaultimp.layerList.resize(3);//这里设置了3层纹理,DDS为一种高级的纹理模式,DirectDrawSurface,觉得难以理解的话
////可以理解为一种特殊的.jpg图片模式,但是用DDS质材的话可以接收并显示地形阴影,用JPG就显示不出来,而且据我调试观
////察发现,第一个.dds质材是用来显示纹理图形,第二个.dds才是用来接收和显示阴影的
//
//	defaultimp.layerList[0].worldSize = 1;//这个值关系到此贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊
//	defaultimp.layerList[0].textureNames.push_back(szCfgFilename);
//	defaultimp.layerList[0].textureNames.push_back(szCfgFilename);
//	defaultimp.layerList[1].worldSize = 1;
//	defaultimp.layerList[1].textureNames.push_back(szCfgFilename);
//	defaultimp.layerList[1].textureNames.push_back(szCfgFilename);
//	defaultimp.layerList[2].worldSize = 2;
//	defaultimp.layerList[2].textureNames.push_back(szCfgFilename);
//	defaultimp.layerList[2].textureNames.push_back(szCfgFilename);
//
//	mTerrainGroup->loadAllTerrains(true);
//
//	if (mTerrainsImported)
//	{
//		TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();
//		while(ti.hasMoreElements())
//		{
//			Terrain* t = ti.getNext()->instance;
//			initBlendMaps(t);
//		}
//	}
//
//	mTerrainGroup->freeTemporaryResources();
//}

void CrisTerrain::testOption()
{
	//mEditMarker = mSceneMgr->createEntity("editMarker", "sphere.mesh");
	//mEditNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	//mEditNode->attachObject(mEditMarker);
	//mEditNode->setScale(0.05, 0.05, 0.05);

	Ogre::FileSystemLayer* mFSLayer = OGRE_NEW_T(Ogre::FileSystemLayer, Ogre::MEMCATEGORY_GENERAL)(OGRE_VERSION_NAME);
	ResourceGroupManager::getSingleton().createResourceGroup("Terrain");
	ResourceGroupManager::getSingleton().addResourceLocation(mFSLayer->getWritablePath(""), "FileSystem", "Terrain", false, false);

	MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC);
	MaterialManager::getSingleton().setDefaultAnisotropy(7);

	//mSceneMgr->setFog(FOG_LINEAR, ColourValue(0.7, 0.7, 0.8), 0, 1000, 2500);

	LogManager::getSingleton().setLogDetail(LL_BOREME);

	mSceneMgr->setAmbientLight(ColourValue(0.6, 0.6, 0.6));

	//// create a few entities on the terrain
	//Entity* e = mSceneMgr->createEntity("tudorhouse.mesh");
	//Vector3 entPos(mTerrainPos.x + 2043, 0, mTerrainPos.z + 1715);
	//Quaternion rot;
	//entPos.y = mTerrainGroup->getHeightAtWorldPosition(entPos) + 65.5 + mTerrainPos.y;
	//rot.FromAngleAxis(Degree(Math::RangeRandom(-180, 180)), Vector3::UNIT_Y);
	//SceneNode* sn = mSceneMgr->getRootSceneNode()->createChildSceneNode(entPos, rot);
	//sn->setScale(Vector3(0.12, 0.12, 0.12));
	//sn->attachObject(e);

	//mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
}

void CrisTerrain::setupContent()
{
	bool blankTerrain = false;
	//blankTerrain = true;

	mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
	//TerrainGlobalOptions是一个类,定义了地形块的一些全局变量和默认值,需要的话我们可以改变他的变量参数,我们后面再做改变。

#ifdef DebugTerrain
	testOption();
#endif

	//创建地形分组Ogre::TerrainGroup
	/*实例化一个TerrainGroup对象
	参数1:为他指定场管理器、
	参数2:地形的平铺方向,平铺方向一般采用ALIGN_X_Z,也就是采用Y作为高度
	参数3:unit16 TERRAINSIZE=2~n+1,比如512+1=513,不符合公式的可能会导致地图显示异常,表示“The
	size of each terrain down one edge in vertices (2^n+1)”楼主只能理解意思,不能完全正确
	表达其中的专有名词,实际调试中,这个参数影响地图边缘的锯齿度,越小锯齿越明显,取值太小
	的话,运行会错误;
	参数4:Real TERRAINWORLDSIZE,地图大小,表示地图正方形的边长)
	*/
	mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, m_sInitData->fMapSize);
	//定义命名前缀
	mTerrainGroup->setFilenameConvention(TERRAIN_FILE_PREFIX, TERRAIN_FILE_SUFFIX);
	//设置了该地形组的起始位置,在以后创建的地形块中均采用此位置作为相对位置
	mTerrainGroup->setOrigin(mTerrainPos);
	mTerrainGroup->setResourceGroup("Terrain");

	//配置地图块参数 configureTerrainDefaults
	configureTerrainDefaults();

	for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)
		for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)
			defineTerrain(x, y, blankTerrain);

	// 开始前加载好
	mTerrainGroup->loadAllTerrains(true);

	if (mTerrainsImported)
	{
		TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();
		while(ti.hasMoreElements())
		{
			Terrain* t = ti.getNext()->instance;
			initBlendMaps(t);
		}
	}

	mTerrainGroup->freeTemporaryResources();
}

void CrisTerrain::getTerrainImage(bool flipX, bool flipY, Image& img)
{
	img.load(m_sInitData->sElevationFilename, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	if (flipX)
		img.flipAroundY();
	if (flipY)
		img.flipAroundX();

}

void CrisTerrain::defineTerrain(long x, long y, bool flat)
{
	// if a file is available, use it
	// if not, generate file from import

	// Usually in a real project you‘ll know whether the compact terrain data is
	// available or not; I‘m doing it this way to save distribution size

	if (flat)
	{
		mTerrainGroup->defineTerrain(x, y, 0.0f);
	}
	else
	{
		String filename = mTerrainGroup->generateFilename(x, y);
		if (ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(), filename))
		{
			mTerrainGroup->defineTerrain(x, y);
		}
		else
		{
			Image img;
			getTerrainImage(x % 2 != 0, y % 2 != 0, img);
			mTerrainGroup->defineTerrain(x, y, &img);
			mTerrainsImported = true;
		}

	}
}

void CrisTerrain::configureTerrainDefaults()
{
	// Configure global
	mTerrainGlobals->setMaxPixelError(8);
	// testing composite map
	mTerrainGlobals->setCompositeMapDistance(3000);//距离镜头超过3000部分使用地图合成(CompositeMap)模式表现
	//mTerrainGlobals->setUseRayBoxDistanceCalculation(true);
	//mTerrainGlobals->getDefaultMaterialGenerator()->setDebugLevel(1);
	//mTerrainGlobals->setLightMapSize(256);

	// Configure default import settings for if we use imported image
	Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
	defaultimp.terrainSize = TERRAIN_SIZE;//不太了解,调试中,这个值越小,地图边缘锯齿现象越严重,太小的话,运行起来程序会跑死、出错
	defaultimp.worldSize = m_sInitData->fMapSize;//假设为a,那么地图大小为 a x a
	defaultimp.inputScale = m_sInitData->fInputScale;//决定地图最大落差(高度),即位图中白色和黑色部分的高度差
	defaultimp.minBatchSize = 33;
	defaultimp.maxBatchSize = 65;
	// textures
	defaultimp.layerList.resize(3);//这里设置了3层纹理,DDS为一种高级的纹理模式,DirectDrawSurface,觉得难以理解的话
//可以理解为一种特殊的.jpg图片模式,但是用DDS质材的话可以接收并显示地形阴影,用JPG就显示不出来,而且据我调试观
//察发现,第一个.dds质材是用来显示纹理图形,第二个.dds才是用来接收和显示阴影的

	defaultimp.layerList[0].worldSize = m_sInitData->fMapSize;//这个值关系到此贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊
	defaultimp.layerList[0].textureNames.push_back(m_sInitData->sMapFilename);
	defaultimp.layerList[0].textureNames.push_back(m_sInitData->sMapFilename);
	defaultimp.layerList[1].worldSize = m_sInitData->fMapSize;
	defaultimp.layerList[1].textureNames.push_back("white2.dds");
	defaultimp.layerList[1].textureNames.push_back("white2.dds");
	defaultimp.layerList[2].worldSize = m_sInitData->fMapSize;
	defaultimp.layerList[2].textureNames.push_back("white2.dds");
	defaultimp.layerList[2].textureNames.push_back("white2.dds");

	//defaultimp.layerList[0].worldSize = 100;//这个值关系到此贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊
	//defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds");
	//defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds");
	//defaultimp.layerList[1].worldSize = 30;
	//defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds");
	//defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds");
	//defaultimp.layerList[2].worldSize = 100;
	//defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");
	//defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");
}

void CrisTerrain::initBlendMaps(Terrain* terrain)
{
	TerrainLayerBlendMap* blendMap0 = terrain->getLayerBlendMap(1);
	TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(2);
	Real minHeight0 = 70;
	Real fadeDist0 = 40;
	Real minHeight1 = 70;
	Real fadeDist1 = 15;
	float* pBlend1 = blendMap1->getBlendPointer();
	for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y)
	{
		for (Ogre::uint16 x = 0; x < terrain->getLayerBlendMapSize(); ++x)
		{
			Real tx, ty;

			blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty);
			Real height = terrain->getHeightAtTerrainPosition(tx, ty);
			Real val = (height - minHeight0) / fadeDist0;
			Math::Clamp(val, (Real)0, (Real)1);

			val = (height - minHeight1) / fadeDist1;
			val = Math::Clamp(val, (Real)0, (Real)1);
			*pBlend1++ = val;

		}
	}
	blendMap0->dirty();
	blendMap1->dirty();
	//blendMap0->loadImage("blendmap1.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	blendMap0->update();
	blendMap1->update();

	// set up a colour map
	/*
	if (!terrain->getGlobalColourMapEnabled())
	{
	terrain->setGlobalColourMapEnabled(true);
	Image colourMap;
	colourMap.load("testcolourmap.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	terrain->getGlobalColourMap()->loadImage(colourMap);
	}
	*/

}

  

时间: 2024-12-29 17:21:40

[Ogre][地形][原创]基于OgreTerrain的地形实现的相关文章

[小明学Shader]15.基于Grid的地形混合shader

1.写在前面 好久没有写博客了,最近面试不太顺利,认识到应该把学习心得或者说是结果都落实到博客上来,一来加深印象,二来有利于自我展示. 本片博客的内容是讲地形纹理混合,是关于手游sgl大地图的shader实现. slg大地图,如cok,是很大的.在渲染时,只渲染屏幕周围的一部分. 在渲染屏幕地形时,会提供一组地形数据,shader会根据地形数据对地形进行混合. 2.混合方法 混合使用的方法是非常常见的纹理混合. 基本原理是为shader提供多张可以选用的地形贴图.然后根据一张alpha贴图或者其

Ogre 编辑器二(用Ogre的地形组件加载天龙八部地形)

主界面如上文设计完成后,场景刚开始添加了是Ogre例子里的,发现场景里实物太少,于是想到直接把天龙的场景拿下来,天龙网上有源码,参考了下,把天龙的地形用Ogre的地形组件完成了下,如下是效果图: 因为主要是加载地形,然后只是简单加载了静态模型,因此场景看着比较简陋,再者因为上传的图片限制,场景复杂后根本传不上来. 天龙的地形还是比较简单的,如下是天龙的pingpan.terrain简化后的内容. <?xml version="1.0" encoding="UTF-8&q

(原创)基于MCU的频率可调,占空比可调的PWM实现(MCU,MCS-51/MSP430)

1.Abstract     做这个是受朋友之邀,用在控制电机转动的方面.他刚好在一家好的单位实习,手头工作比较多,无暇分身,所以找我帮忙做个模型.要求很明晰,PWM的频率在0~1KHz范围内,占空比0~99%范围内,二者均可调.抄下指标以后,回到实验室,细细分析以后,决定用MCU来实现一下,毕竟只分析,无实际结果也不是一个好的交代. 2.Content   2.1 理论分析     归根结底来说,是一个时序逻辑,即PWM输出波形是随着时间的推移而变化.用时序图的方式解释更明晰些. FIG2.1

(原创)基于FPGA的调光流水灯(Verilog,CPLD/FPGA)

1.Abstract     前几天做了一个呼吸灯,觉得确实挺有意思的:可惜的是只有一个灯管亮,板子上有四个灯,要是能让这些灯有序地亮起来,那应该更有趣味了!跟传统的一样,逻辑上做成一个流水灯的样式,这种带有PWM调光的吸引样式,真可谓是超级流水灯了.     做这个是在已做好的呼吸灯的基础上进行添加功能的,整理好了也在随笔里边,这里就直接引用出来.     基于Verilog的PWM呼吸灯:http://www.cnblogs.com/hechengfei/p/4106538.html 2.C

[原创]基于51单片机的红外遥控课程设计

[注]: 一眨眼,大学接近尾声,具有找工作需要,所以把大学做的电子设计“劣作”放上来.希望考研失意,还能赶上“好工作”的春招班车.如果大伙有什么工作推荐也可以联系我哦,因为一年考研少接触了这方面,所以难免有些生疏.但请相信我!给我机会我会很认真学的! 邮箱:[email protected] 转载请注明出处呀! 基于51单片机的红外遥控课程设计 目录 第一章 设计简介... 3 第二章 系统方案... 3 一.设计方案对比... 3 二.方案设计... 4 第三章 硬件设计... 5 一.红外遥

[原创]基于VueJs的前后端分离框架搭建之完全攻略

首先请原谅本文标题取的有点大,但并非为了哗众取宠.本文取这个标题主要有3个原因,这也是写作本文的初衷: (1)目前国内几乎搜索不到全面讲解如何搭建前后端分离框架的文章,讲前后端分离框架思想的就更少了,而笔者希望在本文中能够全面.详细地阐述我们团队在前后端分离的摸索中所得到的搭建思路.最佳实践以及架构思想: (2)我们团队所搭建的前后端分离框架,并非只是将网上传播的知识碎片简单拼装,而是一开始就从全局出发,按照整个系统对前后端分离框架的最高期望进行设计,到目前为止,可以说我们的框架完全实现了对我们

3dmax导入地形数据DEM制作三维地形

工具准备      1.BIGEMAP地图下载器 2.3DMAX软件 3.global mapper Global mepper 下载地址:http://www.bigemap.com/Home/Product/index.html 资料准备 下载你需要 区域的DEM数据和 卫星影像数据. 影像须使用BIGEMAP地图下载器中Google Earth无偏移影像,并具有无Google小水印.免封IP.影像更新更快等特点. 首先在图源列表中选中Google Earth图源,只有此图源可实现高清卫星图

[原创]基于html5新标签canvas写的一个小画板

最近刚学了canvas,写个小应用练习下 源代码 1 <!DOCTYPE> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>無標題文件</title> 6 <script src="http://ajax.googleapis.co

(原创)基于CloudStack的平安云-云主机的生命周期

一.购买云主机1.条件筛选   涉及环境.应用系统.区域.网络.操作系统.套餐.期限.数量筛选2.校验   2.1 应用系统角色权限校验   2.2 应用系统可用配置校验   2.3 产品区域是否下架校验   2.4 网络是否下架.还有网络跟租户关系是否解除校验   2.5 套餐是否下架校验   2.6 cpu.内存是否足够校验   2.7 系统模板是否存在校验   2.8 ROOT盘容量是否足够校验3.订单生成4.日志记录5.清除购物车6.冻结系统配额 二.云主机实施1.任务生成2.获取网络模