note.x | Papervision3Dメモ #11 のハイトマップから地形を生成させるとか note.x | [Papervision3D] 富士山 の標高とか見てたら、でこぼこした地形を扱ってみたくなった。
とりあえず、org.papervision3d.objects.Plane クラスを改造して DekoBokoPlane クラスを作ってみた。
奥行き(高さ)データの二次元配列(配列の配列)を指定することで、デコボコした平面オブジェクトを作ることができる。テクスチャも貼れる。
DekoBokoSample.as
package {
import flash.display.*;
import flash.events.*;
import org.papervision3d.scenes.*;
import org.papervision3d.objects.*;
import org.papervision3d.cameras.*;
import org.papervision3d.materials.*;
[SWF(width="400", height="400", backgroundColor="#000000", frameRate="30")]
// This class is a sample for DekoBokoPlane class.
public class DekoBokoSample extends Sprite {
private var container : Sprite;
private var scene : Scene3D;
private var camera : Camera3D;
private var rootNode : DisplayObject3D;
private var obj:Array = new Array();
// these parameters for dancing 3d object
private var valx : Number = 0;
private var valy : Number = 0;
public function DekoBokoSample():void {
stage.addEventListener(Event.RESIZE, onStageResize);
addEventListener(Event.ENTER_FRAME, myLoopEvent);
// for display
container = new Sprite();
container.x = 400 / 2; // at center : swf width = 400
container.y = 400 / 2; // at center : swf height = 400
addChild(container);
scene = new Scene3D(container);
camera = new Camera3D();
camera.z = -200;
camera.focus = 500;
camera.zoom = 1;
rootNode = new DisplayObject3D();
scene.addChild(rootNode);
// z parameters (depths)
var depths:Array = [
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45],
[ 0, 10, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 15, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 20, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 25, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 30, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 35, 0, 0, -50, -50, 0, 0, 0, 0],
[ 0, 40, 0, 0, -50, -50, 0, 0, 0, 0],
[ 0, 45, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 50, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 55, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 60, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 65, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 70, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 75, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 80, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 85, 0, 0, 0, 0, 0, 0, 0, 100],
];
obj.push(createWireframePlane(depths));
obj.push(createColorPlane(depths));
obj.push(createBitmapPlane(depths));
for(var i:int; i<obj.length; i++){
rootNode.addChild(obj[i]);
}
}
private function createWireframePlane(depths:Array):DisplayObject3D {
var material:WireframeMaterial = new WireframeMaterial();
material.oneSide = false;
material.lineColor = 0x00FF00;
material.lineAlpha = 1;
var planeSize:int = 200;
var plane:DekoBokoPlane = new DekoBokoPlane(
material, planeSize, planeSize, depths);
plane.x = -100;
plane.y = 100;
plane.z = 0;
return plane;
}
private function createColorPlane(depths:Array):DisplayObject3D {
var material:ColorMaterial =
new ColorMaterial(0xFF0000, 1);
material.oneSide = false;
material.lineColor = 0x0000FF;
material.lineAlpha = 1;
var planeSize:int = 200;
var plane:DekoBokoPlane = new DekoBokoPlane(
material, planeSize, planeSize, depths);
plane.x = 100;
plane.y = -100;
plane.z = 0;
return plane;
}
private function createBitmapPlane(depths:Array):DisplayObject3D {
var material:BitmapFileMaterial =
new BitmapFileMaterial("texture.jpg");
material.oneSide = false;
material.lineColor = 0x0000FF;
material.lineAlpha = 1;
var planeSize:int = 200;
var plane:DekoBokoPlane = new DekoBokoPlane(
material, planeSize, planeSize, depths);
plane.x = 0;
plane.y = 0;
plane.z = 0;
return plane;
}
private function myLoopEvent(event:Event):void {
valx += container.mouseX / 50;
valy += container.mouseY / 50;
for(var i:int; i<obj.length; i++){
obj[i].rotationY = valx;
obj[i].rotationX = valy;
}
scene.renderCamera(camera);
}
private function onStageResize(event:Event):void {
container.x = stage.stageWidth / 2;
container.y = stage.stageHeight / 2;
}
}
}
DekoBokoPlane.as
// This source code is based by org.papervision3d.objects.Plane class by Carlos Ulloa Matesanz, noventaynueve.com.
// Copyright 2007 (c) NI-Lab. www.nilab.info
/*
* PAPER ON ERVIS NPAPER ISION PE IS ON PERVI IO APER SI PA
* AP VI ONPA RV IO PA SI PA ER SI NP PE ON AP VI ION AP
* PERVI ON PE VISIO APER IONPA RV IO PA RVIS NP PE IS ONPAPE
* ER NPAPER IS PE ON PE ISIO AP IO PA ER SI NP PER
* RV PA RV SI ERVISI NP ER IO PE VISIO AP VISI PA RV3D
* ______________________________________________________________________
* papervision3d.org + blog.papervision3d.org + osflash.org/papervision3d
*/
/*
* Copyright 2006 (c) Carlos Ulloa Matesanz, noventaynueve.com.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package {
import org.papervision3d.core.*;
import org.papervision3d.core.proto.*;
import org.papervision3d.core.geom.*;
import flash.display.BitmapData;
/**
* The DekoBokoPlane class lets you create and display dekoboko rectangle objects.
*
*/
public class DekoBokoPlane extends Mesh3D
{
public var segmentsW :Number;
public var segmentsH :Number;
static public var DEFAULT_SIZE :Number = 500;
static public var DEFAULT_SCALE :Number = 1;
//static public var DEFAULT_SEGMENTS :Number = 1;
public function DekoBokoPlane(
material:MaterialObject3D=null,
width:Number=0,
height:Number=0,
depths:Array=null,
initObject:Object=null)
{
super( material, new Array(), new Array(), null, initObject );
// for dekoboko
if(depths == null || depths.length < 2 || depths[0].length < 2){
depths = [ [0,0], [0,0] ];
}
this.segmentsW = depths[0].length - 1;
this.segmentsH = depths.length - 1;
var scale :Number = DEFAULT_SCALE;
if( ! height )
{
if( width )
scale = width;
if( material && material.bitmap )
{
width = material.bitmap.width * scale;
height = material.bitmap.height * scale;
}
else
{
width = DEFAULT_SIZE * scale;
height = DEFAULT_SIZE * scale;
}
}
buildPlane( width, height, depths );
}
private function buildPlane( width:Number, height:Number, depths:Array ):void
{
var gridX :Number = this.segmentsW;
var gridY :Number = this.segmentsH;
var gridX1 :Number = gridX + 1;
var gridY1 :Number = gridY + 1;
var vertices :Array = this.geometry.vertices;
var faces :Array = this.geometry.faces;
var textureX :Number = width /2;
var textureY :Number = height /2;
var iW :Number = width / gridX;
var iH :Number = height / gridY;
// Vertices
for( var ix:int = 0; ix < gridX + 1; ix++ )
{
for( var iy:int = 0; iy < gridY1; iy++ )
{
var x :Number = ix * iW - textureX;
var y :Number = iy * iH - textureY;
// for dekoboko
var z:Number = depths[depths.length - 1 - iy][ix];
//vertices.push( new Vertex3D( x, y, 0 ) );
vertices.push( new Vertex3D( x, y, z ) ); // for dekoboko
}
}
// Faces
var uvA :NumberUV;
var uvC :NumberUV;
var uvB :NumberUV;
for( ix = 0; ix < gridX; ix++ )
{
for( iy= 0; iy < gridY; iy++ )
{
// Triangle A
var a:Vertex3D = vertices[ ix * gridY1 + iy ];
var c:Vertex3D = vertices[ ix * gridY1 + (iy+1) ];
var b:Vertex3D = vertices[ (ix+1) * gridY1 + iy ];
uvA = new NumberUV( ix / gridX, iy / gridY );
uvC = new NumberUV( ix / gridX, (iy+1) / gridY );
uvB = new NumberUV( (ix+1) / gridX, iy / gridY );
faces.push( new Face3D( [ a, b, c ], null, [ uvA, uvB, uvC ] ) );
// Triangle B
a = vertices[ (ix+1) * gridY1 + (iy+1) ];
c = vertices[ (ix+1) * gridY1 + iy ];
b = vertices[ ix * gridY1 + (iy+1) ];
uvA = new NumberUV( (ix+1) / gridX, (iy+1) / gridY );
uvC = new NumberUV( (ix+1) / gridX, iy / gridY );
uvB = new NumberUV( ix / gridX, (iy+1) / gridY );
faces.push( new Face3D( [ a, b, c ], null, [ uvA, uvB, uvC ] ) );
}
}
this.geometry.ready = true;
}
}
}
DekoBokoSample-config.xml
<flex-config>
<output>DekoBokoSample.swf</output>
<default-size>
<width>400</width>
<height>400</height>
</default-size>
<default-frame-rate>30</default-frame-rate>
<default-background-color>0x000000</default-background-color>
<use-network>true</use-network>
<benchmark>true</benchmark>
<compiler>
<incremental>true</incremental>
<source-path>
<path-element>../libs/</path-element>
</source-path>
</compiler>
</flex-config>
../libs/ 以下に Papervision3D 1.5 のソースコードを設置。
コンパイル風景
Flex 2.0.1 にてコンパイル。
mxmlc DekoBokoSample.as
DekoBokoSample.swf が生成される。
tags: zlashdot Flash Flash Flex Papervision3D
Posted by NI-Lab. (@nilab)