3D 地形
あやしいところ、いっぱい。リアルタイムに動かそうとしたら重いのでやめた。
/**
* Copyright gaziya ( http://wonderfl.net/user/gaziya )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/emvC
*/
package {
import flash.geom.Utils3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Point;
import flash.filters.ColorMatrixFilter;
import flash.display.BlendMode
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.geom.ColorTransform;
import flash.events.Event;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
var bmds:Vector.<BitmapData> = new Vector.<BitmapData>
for (var i:int=0; i<5; i++) {
bmds.push(new BitmapData(300,300, false))
var bitmap:Bitmap = addChild(new Bitmap(bmds[i])) as Bitmap
bitmap.x = (90)*i+15
bitmap.y = 5
bitmap.width = 80
bitmap.height = 80
}
bmds[0].perlinNoise(80, 120, 7, Math.random() * 100, true, true, 8, true)
bmds[0].colorTransform(bmds[1].rect, new ColorTransform(1.5, 1.5, 1.5, 1, -0x40, -0x40, -0x40))
var paletteR:Array = []
var paletteG:Array = []
var paletteB:Array = []
var seaHeight:uint = 0x40
var r:Number
for (i=0; i<256; i++) {
if (i > seaHeight) {
r = (i - seaHeight) / (256 - seaHeight)
if (r > 0.7) {
paletteR[i] = (0x99 + 0x66 * (r - 0.7) / (1 - 0.7)) << 16
paletteG[i] = (0x66 + 0x99 * (r - 0.7) / (1 - 0.7)) << 8
paletteB[i] = (0x00 + 0xFF * (r - 0.7) / (1 - 0.7))
} else if (r > 0.15) {
paletteR[i] = (0x00 + 0x99 * (r - 0.15) / (0.7 - 0.15)) << 16
paletteG[i] = (0xCC - 0x66 * (r - 0.15) / (0.7 - 0.15)) << 8
paletteB[i] = (0x00 + 0x00 * (r - 0.15) / (0.7 - 0.15))
} else {
paletteR[i] = (0xCC - 0xCC * r / 0.15) << 16
paletteG[i] = (0x99 + 0x33 * r / 0.15) << 8
paletteB[i] = (0x33 - 0x33 * r / 0.15)
}
} else {
r = i / seaHeight
paletteR[i] = 0
paletteG[i] = Math.pow(r, 5) * 0x66 << 8
paletteB[i] = (r * 0.5 + 0.5) * 0xFF
}
}
bmds[1].paletteMap(bmds[0], bmds[0].rect,new Point, paletteR, paletteG, paletteB)
var vector:Vector3D = new Vector3D
var matrix:Matrix3D = new Matrix3D
var multiplier:Number = 25
for (var y:int=0; y<bmds[0].height; y++) {
for (var x:int=0; x<bmds[0].width; x++) {
var height:uint = bmds[0].getPixel(x, y) & 0xFF
vector.x = (height - (bmds[0].getPixel((x + 1) % bmds[0].width, y) & 0xFF)) / 0xFF * multiplier
vector.y = (height - (bmds[0].getPixel(x, (y + 1) % bmds[0].height) & 0xFF)) / 0xFF * multiplier
vector.y *= -1
vector.z = 0
if (vector.lengthSquared > 1) {
vector.normalize();
}
vector.z = Math.sqrt(1 - vector.lengthSquared)
matrix.identity()
matrix.appendRotation(y / bmds[0].height * 180 - 90, Vector3D.X_AXIS)
matrix.appendRotation(x / bmds[0].width * 360, Vector3D.Y_AXIS)
vector = matrix.transformVector(vector)
bmds[2].setPixel(x, y,
(vector.x * 0x7F + 0x80) << 16 |
(vector.y * 0x7F + 0x80) << 8 |
(vector.z * 0x7F + 0x80)
)
}
}
bmds[3].applyFilter(bmds[2], bmds[2].rect,new Point, new ColorMatrixFilter([
1/3, 1/3, 1/3, 0, 0,
1/3, 1/3, 1/3, 0, 0,
1/3, 1/3, 1/3, 0, 0,
0 , 0, 0, 1, 0
]))
bmds[4].copyPixels(bmds[3],bmds[3].rect, bmds[3].rect.topLeft)
bmds[4].draw(bmds[1], null, null, BlendMode.MULTIPLY)
var geography:Object = new Object
geography.vertices = new Vector.<Number>
geography.indices = new Vector.<int>
geography.uvtData = new Vector.<Number>
for (y=0; y <= bmds[0].height; y++) {
for (x=0; x <= bmds[0].width; x++) {
var perX:Number = x/bmds[0].width
var perY:Number = y/bmds[0].height
height = bmds[0].getPixel(x, y) & 0xff
geography.vertices.push(
perX-0.5,
perY-0.5,
(height > seaHeight)? (height-seaHeight)/(0xff*8): 0
)
i = (bmds[0].width)*y+x
geography.indices.push(
i, i+1, i+bmds[0].width+1,
i+1, i+bmds[0].width+2, i+bmds[0].width+1
)
geography.uvtData.push(perX, perY, 0)
}
}
var pers:PerspectiveProjection = new PerspectiveProjection
var persMatrix:Matrix3D = pers.toMatrix3D()
var worldMatrix:Matrix3D = new Matrix3D
with (worldMatrix) {
identity()
appendRotation(-65,Vector3D.X_AXIS)
appendTranslation(0,0,-0.7)
append(persMatrix)
}
var persVerts:Vector.<Number> = new Vector.<Number>
Utils3D.projectVectors(worldMatrix, geography.vertices, persVerts, geography.uvtData)
persVerts.map(function(item:Number, index:int, vector:Vector.<Number>):void {
vector[index] += (index%2==0) ? stage.stageWidth/2 : stage.stageHeight/2
})
with (graphics) {
clear()
beginBitmapFill(bmds[4])
drawTriangles(persVerts, geography.indices, geography.uvtData, 'negative')
}
}
}
}