Explorar o código

basic scene / mesh

ncannasse %!s(int64=12) %!d(string=hai) anos
pai
achega
0a550bbcd4
Modificáronse 9 ficheiros con 387 adicións e 40 borrados
  1. 47 0
      h3d/Engine.hx
  2. 9 0
      h3d/mat/MeshMaterial.hx
  3. 38 0
      h3d/mat/MeshTexture.hx
  4. 4 0
      h3d/mat/Texture.hx
  5. 47 0
      h3d/scene/Layers.hx
  6. 20 0
      h3d/scene/Mesh.hx
  7. 180 0
      h3d/scene/Object.hx
  8. 22 0
      h3d/scene/Scene.hx
  9. 20 40
      samples/Test.hx

+ 47 - 0
h3d/Engine.hx

@@ -28,6 +28,12 @@ class Engine {
 	var antiAlias : Int;
 	var inTarget : Bool;
 
+	var debugPoint : h3d.CoreObject<h3d.impl.Shaders.PointShader>;
+	var debugLine : h3d.CoreObject<h3d.impl.Shaders.LineShader>;
+	
+	@:allow(h3d)
+	var curProjMatrix : h3d.Matrix;
+
 	public function new( width = 0, height = 0, hardware = true, aa = 0, stageIndex = 0 ) {
 		if( width == 0 )
 			width = Caps.width;
@@ -287,6 +293,7 @@ class Engine {
 		curMatBits = -1;
 		curShader = null;
 		curBuffer = null;
+		curProjMatrix = null;
 		curTextures = [];
 		return true;
 	}
@@ -295,6 +302,7 @@ class Engine {
 		curMatBits = -1;
 		curShader = null;
 		curBuffer = null;
+		curProjMatrix = null;
 		for( i in 0...curAttributes )
 			ctx.setVertexBufferAt(i, null);
 		curAttributes = 0;
@@ -335,6 +343,45 @@ class Engine {
 		end();
 		return true;
 	}
+	
+	// debug functions
+	public function point( x : Float, y : Float, z : Float, color = 0x80FF0000, size = 1.0, depth = false ) {
+		if( curProjMatrix == null )
+			return;
+		if( debugPoint == null ) {
+			debugPoint = new h3d.CoreObject(new h3d.prim.Plan2D(), new h3d.impl.Shaders.PointShader());
+			debugPoint.material.blend(SrcAlpha, OneMinusSrcAlpha);
+			debugPoint.material.depthWrite = false;
+		}
+		debugPoint.material.depthTest = depth ? h3d.mat.Data.Compare.LessEqual : h3d.mat.Data.Compare.Always;
+		debugPoint.shader.mproj = curProjMatrix;
+		debugPoint.shader.delta = new h3d.Vector(x, y, z, 1);
+		var gscale = 1 / 200;
+		debugPoint.shader.size = new h3d.Vector(size * gscale, size * gscale * width / height);
+		debugPoint.shader.color = color;
+		debugPoint.render(h3d.Engine.getCurrent());
+	}
+
+	public function line( x1 : Float, y1 : Float, z1 : Float, x2 : Float, y2 : Float, z2 : Float, color = 0x80FF0000, depth = false ) {
+		if( curProjMatrix == null )
+			return;
+		if( debugLine == null ) {
+			debugLine = new h3d.CoreObject(new h3d.prim.Plan2D(), new h3d.impl.Shaders.LineShader());
+			debugLine.material.blend(SrcAlpha, OneMinusSrcAlpha);
+			debugLine.material.depthWrite = false;
+			debugLine.material.culling = None;
+		}
+		debugLine.material.depthTest = depth ? h3d.mat.Data.Compare.LessEqual : h3d.mat.Data.Compare.Always;
+		debugLine.shader.mproj = curProjMatrix;
+		debugLine.shader.start = new h3d.Vector(x1, y1, z1);
+		debugLine.shader.end = new h3d.Vector(x2, y2, z2);
+		debugLine.shader.color = color;
+		debugLine.render(h3d.Engine.getCurrent());
+	}
+
+	public function lineP( a : { x : Float, y : Float, z : Float }, b : { x : Float, y : Float, z : Float }, color = 0x80FF0000, depth = false ) {
+		line(a.x, a.y, a.z, b.x, b.y, b.z, color, depth);
+	}
 
 	public function dispose() {
 		s3d.removeEventListener(flash.events.Event.CONTEXT3D_CREATE, onCreate);

+ 9 - 0
h3d/mat/MeshMaterial.hx

@@ -0,0 +1,9 @@
+package h3d.mat;
+
+class MeshMaterial extends Material {
+	
+	public function setMatrixes( mpos : h3d.Matrix, mproj : h3d.Matrix ) {
+		throw "Not implemented";
+	}
+	
+}

+ 38 - 0
h3d/mat/MeshTexture.hx

@@ -0,0 +1,38 @@
+package h3d.mat;
+
+private class Shader extends h3d.Shader {
+	static var SRC = {
+		var input : {
+			pos : Float3,
+			uv : Float2,
+		};
+		var tuv : Float2;
+		function vertex( mpos : Matrix, mproj : Matrix ) {
+			out = pos.xyzw * mpos * mproj;
+			tuv = uv;
+		}
+		function fragment( tex : Texture ) {
+			out = tex.get(tuv.xy);
+		}
+	}
+}
+
+class MeshTexture extends MeshMaterial {
+
+	static var SHADER = new Shader();
+	
+	public var texture : Texture;
+	
+	public function new(texture) {
+		super(SHADER);
+		this.texture = texture;
+	}
+	
+	public override function setMatrixes( mpos, mproj ) {
+		var s = SHADER;
+		s.mpos = mpos;
+		s.mproj = mproj;
+		s.tex = texture;
+	}
+	
+}

+ 4 - 0
h3d/mat/Texture.hx

@@ -66,5 +66,9 @@ class Texture {
 		if( t != null )
 			mem.deleteTexture(this);
 	}
+	
+	public static function ofBitmap( bmp : flash.display.BitmapData ) {
+		return h3d.Engine.getCurrent().mem.makeTexture(bmp);
+	}
 
 }

+ 47 - 0
h3d/scene/Layers.hx

@@ -0,0 +1,47 @@
+package h3d.scene;
+
+class Layers extends Object {
+	
+	// the per-layer insert position
+	var layers : Array<Int>;
+	var layerCount : Int;
+	
+	public function new(?parent) {
+		super(parent);
+		layers = [];
+		layerCount = 0;
+	}
+	
+	override function addChild(o) {
+		addChildAt(o, layers.length);
+	}
+	
+	public inline function add(o, layer) {
+		return addChildAt(o, layer);
+	}
+	
+	override function addChildAt( o : Object, layer : Int ) {
+		// new layer
+		while( layer >= layerCount )
+			layers[layerCount++] = childs.length;
+		super.addChildAt(o,layers[layer]);
+		for( i in layer...layerCount )
+			layers[i]++;
+	}
+	
+	override function removeChild( o : Object ) {
+		for( i in 0...childs.length ) {
+			if( childs[i] == o ) {
+				childs.splice(i, 1);
+				o.parent = null;
+				var k = layerCount - 1;
+				while( k >= 0 && layers[k] > i ) {
+					layers[k]--;
+					k--;
+				}
+				break;
+			}
+		}
+	}
+	
+}

+ 20 - 0
h3d/scene/Mesh.hx

@@ -0,0 +1,20 @@
+package h3d.scene;
+
+class Mesh extends Object {
+
+	public var primitive : h3d.prim.Primitive;
+	public var material : h3d.mat.MeshMaterial;
+	
+	public function new( prim, mat, ?parent ) {
+		super(parent);
+		this.primitive = prim;
+		this.material = mat;
+	}
+	
+	override function draw( engine : h3d.Engine ) {
+		material.setMatrixes(this.absPos, engine.curProjMatrix);
+		engine.selectMaterial(material);
+		primitive.render(engine);
+	}
+	
+}

+ 180 - 0
h3d/scene/Object.hx

@@ -0,0 +1,180 @@
+package h3d.scene;
+
+class Object {
+
+	static inline var ROT2RAD = -0.017453292519943295769236907684886;
+	
+	var childs : Array<Object>;
+	public var parent(default,null) : Object;
+	
+	public var x(default,set) : Float;
+	public var y(default, set) : Float;
+	public var z(default, set) : Float;
+	public var scaleX(default,set) : Float;
+	public var scaleY(default, set) : Float;
+	public var scaleZ(default,set) : Float;
+
+	var absPos : h3d.Matrix;
+	var qRot : h3d.Quat;
+	var posChanged : Bool;
+	
+	public function new( ?parent : Object ) {
+		absPos = new h3d.Matrix();
+		absPos.identity();
+		x = 0; y = 0; z = 0; scaleX = 1; scaleY = 1; scaleZ = 0;
+		qRot = new h3d.Quat();
+		posChanged = false;
+		childs = [];
+		if( parent != null )
+			parent.addChild(this);
+	}
+	
+	public function getObjectsCount() {
+		var k = 0;
+		for( c in childs )
+			k += c.getObjectsCount() + 1;
+		return k;
+	}
+	
+	public function addChild( o : Object ) {
+		addChildAt(o, childs.length);
+	}
+	
+	public function addChildAt( o : Object, pos : Int ) {
+		if( pos < 0 ) pos = 0;
+		if( pos > childs.length ) pos = childs.length;
+		var p = this;
+		while( p != null ) {
+			if( p == o ) throw "Recursive addChild";
+			p = p.parent;
+		}
+		if( o.parent != null )
+			o.parent.removeChild(o);
+		childs.insert(pos,o);
+		o.parent = this;
+		o.posChanged = true;
+	}
+	
+	public function removeChild( o : Object ) {
+		if( childs.remove(o) )
+			o.parent = null;
+	}
+	
+	// shortcut for parent.removeChild
+	public inline function remove() {
+		if( this != null && parent != null ) parent.removeChild(this);
+	}
+	
+	function draw( engine : h3d.Engine ) {
+	}
+	
+	function updatePos() {
+		if( parent != null && parent.posChanged )
+			posChanged = true;
+		if( posChanged ) {
+			qRot.saveToMatrix(absPos);
+			// prepend scale
+			absPos._11 *= scaleX;
+			absPos._12 *= scaleX;
+			absPos._13 *= scaleX;
+			absPos._21 *= scaleY;
+			absPos._22 *= scaleY;
+			absPos._23 *= scaleY;
+			absPos._31 *= scaleY;
+			absPos._32 *= scaleY;
+			absPos._33 *= scaleY;
+			absPos._41 = x;
+			absPos._42 = y;
+			absPos._43 = z;
+			if( parent != null )
+				absPos.multiply3x4(absPos, parent.absPos);
+		}
+	}
+	
+	function render( engine : h3d.Engine ) {
+		updatePos();
+		draw(engine);
+		for( c in childs )
+			c.render(engine);
+		posChanged = false;
+	}
+	
+	inline function set_x(v) {
+		x = v;
+		posChanged = true;
+		return v;
+	}
+
+	inline function set_y(v) {
+		y = v;
+		posChanged = true;
+		return v;
+	}
+
+	inline function set_z(v) {
+		z = v;
+		posChanged = true;
+		return v;
+	}
+	
+	inline function set_scaleX(v) {
+		scaleX = v;
+		posChanged = true;
+		return v;
+	}
+	
+	inline function set_scaleY(v) {
+		scaleY = v;
+		posChanged = true;
+		return v;
+	}
+
+	inline function set_scaleZ(v) {
+		scaleZ = v;
+		posChanged = true;
+		return v;
+	}
+	
+	/*
+		Move along the current rotation axis
+	*/
+	public function move( dx : Float, dy : Float, dz : Float ) {
+		throw "TODO";
+	}
+
+	public inline function setPos( x : Float, y : Float, z : Float ) {
+		this.x = x;
+		this.y = y;
+		this.z = z;
+	}
+	
+	/*
+		Rotate around the current rotation axis.
+	*/
+	public function rotate( rx : Float, ry : Float, rz : Float ) {
+		throw "TODO";
+	}
+	
+	public function setRotate( rx : Float, ry : Float, rz : Float ) {
+		qRot.initRotation(rx, ry, rz);
+		posChanged = true;
+	}
+	
+	public function setRotateAxis( ax : Float, ay : Float, az : Float, angle : Float ) {
+		qRot.initAxis(ax, ay, az, angle);
+		posChanged = true;
+	}
+	
+	public inline function scale( v : Float ) {
+		scaleX *= v;
+		scaleY *= v;
+		scaleZ *= v;
+	}
+	
+	public inline function setScale( v : Float ) {
+		scaleX = v;
+		scaleY = v;
+		scaleZ = v;
+	}
+	
+}

+ 22 - 0
h3d/scene/Scene.hx

@@ -0,0 +1,22 @@
+package h3d.scene;
+
+class Scene extends Layers {
+
+	public var camera : h3d.Camera;
+	
+	public function new() {
+		super(null);
+		camera = new h3d.Camera();
+	}
+	
+	// make it public
+	public override function render( engine : h3d.Engine ) {
+		camera.ratio = engine.width / engine.height;
+		camera.update();
+		var oldProj = engine.curProjMatrix;
+		engine.curProjMatrix = camera.m;
+		super.render(engine);
+		engine.curProjMatrix = oldProj;
+	}
+	
+}

+ 20 - 40
samples/Test.hx

@@ -1,67 +1,47 @@
-class RGBShader extends h3d.Shader {
-	
-	static var SRC = {
-		var input : {
-			pos : Float3,
-			uv : Float2,
-		};
-		var tuv : Float2;
-		
-		function vertex( mproj : M44 ) {
-			out = pos.xyzw * mproj;
-			tuv = uv;
-		}
-		function fragment( tex : Texture ) {
-			out = tex.get(tuv.xy);
-		}
-	}
-	
-}
+import h3d.scene.*;
 
 class Test {
 	
 	var root : flash.display.Sprite;
-	var e : h3d.Engine;
+	var engine : h3d.Engine;
 	var time : Float;
-	var camera : h3d.Camera;
-	var obj : h3d.CoreObject<RGBShader>;
+	var scene : Scene;
+	var obj1 : Mesh;
+	var obj2 : Mesh;
 	
 	function new(root) {
 		this.root = root;
 		time = 0;
-		e = new h3d.Engine();
-		camera = new h3d.Camera();
-		e.debug = true;
-		e.backgroundColor = 0x202020;
-		e.onReady = start;
-		e.init();
+		engine = new h3d.Engine();
+		engine.debug = true;
+		engine.backgroundColor = 0x202020;
+		engine.onReady = start;
+		engine.init();
 	}
 	
 	function start() {
 		root.addEventListener(flash.events.Event.ENTER_FRAME, update);
-		var rgb = new RGBShader();
+		
 		var prim = new h3d.prim.Cube();
 		prim.translate( -0.5, -0.5, -0.5);
 		prim.addTCoords();
-		obj = new h3d.CoreObject(prim, rgb);
+		
 		var bmp = new flash.display.BitmapData(256, 256);
 		bmp.perlinNoise(64, 64, 3, 0, true, true, 7);
-		rgb.tex = e.mem.makeTexture(bmp);
+		var mat = new h3d.mat.MeshTexture(h3d.mat.Texture.ofBitmap(bmp));
 		bmp.dispose();
+		
+		scene = new Scene();
+		obj1 = new Mesh(prim, mat, scene);
+		obj2 = new Mesh(prim, mat, scene);
 	}
 	
 	function update(_) {
 		var dist = 5;
 		time += 0.01;
-		camera.pos.set(Math.cos(time) * dist, Math.sin(time) * dist, 3);
-		camera.update();
-		obj.shader.mproj = camera.m;
-		e.begin();
-		obj.render(e);
-		camera.m.prependRotate(new h3d.Vector(-0.5, 2, Math.cos(time)), time + Math.PI / 2);
-		obj.shader.mproj = camera.m;
-		obj.render(e);
-		e.end();
+		scene.camera.pos.set(Math.cos(time) * dist, Math.sin(time) * dist, 3);
+		obj2.setRotateAxis(-0.5, 2, Math.cos(time), time + Math.PI / 2);
+		engine.render(scene);
 	}
 	
 	static function main() {