------------------------------------------------------------------------------- -- 创建,导入,导出,修改地形. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- 从高度图导入地形 ------------------------------------------------------------------------------- fn SYImportTerrain HeightScale = ( -- 打开位图浏览对话框 b = selectbitmap() -- 获得文件名 if b != undefined then bname = (getfilenamefile b.filename) else return undefined -- 获得宽度和高度 w = b.width h = b.height if w!=h then ( messagebox("高度图宽度和高度不相等!") return undefined ) SYTerrSize = w; local terrainObject local temp -- 检查所有的节点,如果节点名为"sy_terrain" 则地形已经存在. for i = 1 to rootnode.children.count do if ( rootnode.children[i].name == "sy_terrain" ) then temp = rootnode.children[i] else temp = undefined if temp != undefined then ( -- 找到节点,修改地形网格 if (temp.verts.count == (w * h)) then ( terrainObject = temp ) else ( terrainObject = plane length:1024 \ width:1024 \ lengthsegs:(w - 1) \ widthsegs:(w - 1) \ wireColor: blue ) ) else ( -- 没有找到节点,创建一个plane grid 网格 terrainObject = plane length:1024 \ width:1024 \ lengthsegs:(w - 1) \ widthsegs:(w - 1) \ wireColor: blue ) terrainObject.name = "sy_terrain" clearUndoBuffer() -- 地形缩放 tmp2 = (w * h) -- ROW for r=0 to h-1 do ( -- 获得行象素 pixels = getpixels b [0,r] w -- 每一列 for c=1 to w do ( -- 象素 p = pixels[c] -- 修改MESH 高度 使用红色通道,可以混用RGB*,GRAY SCALE. terrainObject.verts[c + r*h].pos.z = ((p.r as integer) * HeightScale) ) ) clearUndoBuffer() -- 关闭修改器堆栈. collapseStack terrainObject clearUndoBuffer() -- 加入UVW修改器 addModifier terrainObject (Uvwmap()) collapseStack terrainObject clearUndoBuffer() select terrainObject return b.filename ) -- 创建地形 -- Size : 顶点数个, Grid 顶点间隔 fn SYCreateTerrain XSize YSize Grid = ( local terrainObject local temp -- 检查所有的节点,如果节点名为"sy_terrain" 则地形已经存在. for i = 1 to rootnode.children.count do if ( rootnode.children[i].name == "sy_terrain" ) then temp = rootnode.children[i] else temp = undefined local XLen = XSize*Grid local YLen = YSize*Grid if temp == undefined then ( terrainObject = plane length:YLen \ width:XLen \ lengthsegs:(YSize - 1) \ widthsegs:(XSize - 1) \ wireColor: blue terrainObject.name = "sy_terrain" clearUndoBuffer() collapseStack terrainObject clearUndoBuffer() addModifier terrainObject (Uvwmap()) collapseStack terrainObject clearUndoBuffer() SYTerrSize = XSize -- 记录地形大小 SYTerrGrid = Grid --setUserProp terrainObject "SY_TerrSize" Size setUserProp terrainObject "SY_TerrGrid" Grid setUserProp terrainObject "SY_XSize" XSize setUserProp terrainObject "SY_YSize" YSize select terrainObject )else messagebox "节点 sy_terrain 已经存在." ) fn SYPT_startStroke = ( --messagebox("start") local pobj=$.baseobject SYTerrHeightTrack =#() for i=1 to (meshOP.getNumVerts pObj) do --meshOP.getNumVerts pObj物体点的数量 ( try( append SYTerrHeightTrack (meshOP.getVert pObj i).z ) catch()--添加每个点的坐标到globalPolySculptVPos矩阵中 ) ) fn SYPT_endStroke = ( --messagebox("end") local pobj=$.baseobject--获得选中物体的修改层属性,返回Editable Poly或其他 SYTerrHeightTrack =#()--设置globalPolySculptVPos矩阵为空 for i=1 to (meshOP.getNumVerts pObj) do ( --添加每个点的坐标到globalPolySculptVPos矩阵中??不明白为什么要加这个,好像一点用处都没有啊 try( append SYTerrHeightTrack (meshOP.getVert pObj i) ) catch() ) ) fn SYPT_cancelStroke = ( --messagebox("cancel") if SYTerrPaintButton != undefined then ( SYTerrPaintButton.checked=false ) SYTerrHeightTrack = undefined ) fn SYPT_systemEnd = ( --messagebox("end") if SYTerrPaintButton != undefined then ( SYTerrPaintButton.checked=false ) SYTerrHeightTrack = undefined ) fn SYPT_Higher = ( -- messagebox("higher") pobj=$.baseobject --获得选中物体的修改层属性,返回Editable Poly或其他 vertBitArray = thePainterInterface.getPointGatherHits $--获得笔刷单击位置的所有点 vertArray = for v in vertBitArray collect v --将获得的点转到verarray with redraw off ( for i=1 to vertArray.count do ( local vPos =thePainterInterface.getPointGatherPoint $ vertArray[i]--返回点的位置 local vWgt =thePainterInterface.getPointGatherWeight $ vertArray[i]--返回笔刷对点的压力 --如果此时按下ALT键点的压力*-1,即反方向 if keyboard.altPressed == true then vWgt *= -1 --点的新坐标=点的法线方向*(压力*笔刷的最大压力)+globalPolySculptVPos矩阵中点的坐标 local newPos = meshOP.getVert pObj vertArray[i] newPos.z = SYTerrHeightTrack[vertArray[i]] + vWgt*thePainterInterface.maxStr --local newPos = [0,0,vWgt*thePainterInterface.maxStr] + SYTerrHeightTrack[vertArray[i]] meshOP.setVert pObj vertArray[i] newPos --设置物体点的坐标为新坐标 ) ) ) fn SYPT_Lower = ( -- messagebox("lower") pObj=$.baseobject --获得选中物体的修改层属性,返回Editable Poly或其他 vertBitArray = thePainterInterface.getPointGatherHits $--获得笔刷单击位置的所有点 vertArray = for v in vertBitArray collect v --将获得的点转到verarray with redraw off ( for i=1 to vertArray.count do ( local vPos =thePainterInterface.getPointGatherPoint $ vertArray[i]--返回点的位置 local vWgt =thePainterInterface.getPointGatherWeight $ vertArray[i]--返回笔刷对点的压力 if keyboard.altPressed == true then vWgt *= -1--如果此时按下ALT键点的压力*-1,即反方向 local newPos = meshOP.getVert pObj vertArray[i] newPos.z = SYTerrHeightTrack[vertArray[i]] - vWgt*thePainterInterface.maxStr meshOP.setVert pObj vertArray[i] newPos --设置物体点的坐标为新坐标 ) ) ) fn SYPT_Smooth = ( pObj=$.baseobject vertBitArray = thePainterInterface.getPointGatherHits $--获得笔刷点击位置的所有点 vertArray = for v in vertBitArray collect v--将点存到VertArray矩阵中 with redraw off ( local vertPos = #() for i=1 to vertArray.count do ( local edgeArr = for j in (meshOP.getEdgesUsingVert $ vertArray[i]) collect j local edgePos = 0 for j in edgeArr do ( eVertArr = for k in (meshOP.getVertsUsingEdge $ j) collect k edgePos += ((SYTerrHeightTrack[evertArr[1]]) + (SYTerrHeightTrack[eVertArr[2]]))/2--取得2个顶点的中间值 ) append vertPos (edgePos/edgeArr.count) ) for i=1 to vertArray.count do ( local newPos = meshOP.getVert pObj vertArray[i] newPos.z = vertPos[i] meshOP.setVert pObj vertArray[i] newPos ) ) ) fn SYPT_AdjustXY = ( local Terrain -- 检查所有的节点,如果节点名为"sy_terrain" 则地形已经存在. for i = 1 to rootnode.children.count do ( if ( rootnode.children[i].name == "sy_terrain" ) then Terrain = rootnode.children[i] else Terrain = undefined ) if (Terrain != undefined) then ( local XSize = getUserProp Terrain "SY_XSize" local YSize = getUserProp Terrain "SY_YSize" local TerrGrid = getUserProp Terrain "SY_TerrGrid" if(XSize != undefined and TerrGrid != undefined) then ( local left = -(XSize/2)*TerrGrid local top = -(YSize/2)*TerrGrid progressstart "校正地形顶点..." for r=0 to YSize-1 do ( progressupdate(100.0*r/YSize) for c=1 to XSize do ( local newPos = meshOP.getVert Terrain (c + r*XSize) newPos.x = left + c*TerrGrid newPos.y = top + r*TerrGrid meshOP.setVert Terrain (c + r*XSize) newPos ) ) progressend(); ) ) else ( ) )