vujadin / BabylonHx

Port of Babylon.js 3D engine to Haxe.
http:/paradoxplay.com/babylonhx
Apache License 2.0
187 stars 43 forks source link

Texture and Light issue #134

Open ramsestom opened 7 years ago

ramsestom commented 7 years ago

I have an issue with texture lightening.

I made an example in babylonjs playground that works fine: http://www.babylonjs-playground.com/#F3TFY#3

But in babylonHx, here is what I have: babylonhx_texture_issue

You can see in the center a white square. It is supposed to be blue...

Here is the babylonHX source code of my example:

package;

import com.babylonhx.cameras.FreeCamera;
import com.babylonhx.lights.DirectionalLight;
import com.babylonhx.lights.HemisphericLight;
import com.babylonhx.lights.PointLight;
import com.babylonhx.materials.MultiMaterial;
import com.babylonhx.materials.PBRMaterial;
import com.babylonhx.materials.textures.RawTexture;
import com.babylonhx.math.Color3;
import com.babylonhx.mesh.MeshBuilder;
import com.babylonhx.mesh.SubMesh;
import com.babylonhx.mesh.VertexBuffer;
import com.babylonhx.mesh.primitives.Box;
import com.babylonhx.physics.PhysicsBodyCreationOptions;
import com.babylonhx.tools.EventState;
import com.babylonhx.tools.Tools;
import com.babylonhx.utils.Image;
import com.babylonhx.utils.typedarray.UInt8Array;
import com.babylonhx.cameras.ArcRotateCamera;
import com.babylonhx.Engine;
import com.babylonhx.materials.Material;
import com.babylonhx.materials.StandardMaterial;
import com.babylonhx.materials.textures.Texture;
import com.babylonhx.math.Vector3;
import com.babylonhx.math.Space;
import com.babylonhx.mesh.Mesh;
import com.babylonhx.Scene; 
import com.babylonhx.physics.PhysicsEngine;
import openfl.Assets;
import openfl.display.BitmapData;
import openfl.display.Sprite;
import openfl.events.Event;
import openfl.events.MouseEvent;
import openfl.geom.Point;
import openfl.geom.Vector3D;
import openfl.geom.Matrix3D;
import openfl.Lib;
import openfl.Vector;

class PhysicTextureIssueTest extends Sprite {

    private var scene:Scene;
    private var engine:Engine;

    private var mouse_clicked_start_time:Int;
    private var mouse_clicked_start_pos:Point;

    private var rotationAxis:Vector3;
    private var rotationAngle:Float;
    private var animationSpeed:Float = 0.05; //percent of rotation animation at each frame
    private var animationCount:Float = 0;

    private var _cube:Mesh;
    private var _cube_dimension:Int = 500;

    public function new() 
    {
        super();

        stage.addChild(this);

        engine = new Engine(this, false);   
        scene = new Scene(engine);

        engine.width = stage.stageWidth;
        engine.height = stage.stageHeight;

        //Create camera and light
        var camera = new ArcRotateCamera("Camera", 0, 0, 0, Vector3.Zero(), scene);
        camera.setPosition(new Vector3(0, 0, -_cube_dimension*2.5));
        camera.attachControl();

        var light = new PointLight("Omni", new Vector3( 0, 0, -_cube_dimension * 2.5), scene);

        //create scene objects
        createScene();

        stage.addEventListener(Event.RESIZE, resize);
        stage.addEventListener(Event.ENTER_FRAME, update);
        stage.addEventListener (MouseEvent.MOUSE_DOWN, onMouseDown);
        stage.addEventListener (MouseEvent.MOUSE_UP, onMouseUp);

        scene.registerBeforeRender(function(scene:Scene, ?es:EventState) {
            light.position = camera.position;
        });

        scene.getEngine().runRenderLoop(function () {
            scene.render();
        });

        enableOpenFL2D();
    }

    private function enableOpenFL2D():Void {
        var openflCameraMask:Int = 0xF0E1D2;
        var mainCamera = scene.activeCamera;
        if (scene.activeCameras.indexOf(mainCamera) == -1) {
            scene.activeCameras.push(mainCamera);
        }
        var openflCamera = new FreeCamera("openfl_nme_dummycamera", new Vector3(Math.POSITIVE_INFINITY, Math.POSITIVE_INFINITY, Math.POSITIVE_INFINITY), scene);
        openflCamera.fov = 0;
        openflCamera.layerMask = openflCameraMask; 
        var openflDummyMesh = Mesh.CreatePlane("openfl_nme_dummymesh", 0.1, scene);
        var openflDummyMaterial = new StandardMaterial("openfl_nme_DummyMaterial", scene);
        openflDummyMaterial.backFaceCulling = false;
        openflDummyMesh.material = openflDummyMaterial;
        openflDummyMesh.layerMask = openflCameraMask;
        scene.activeCameras.push(openflCamera);
    }

        private function createScene()
    {
        _cube = new Mesh("cube", scene);
        createInsideMesh();
    }

    private function createInsideMesh()
    {
        var _cell_width:Float = _cube_dimension / 10;
        var _cell_height:Float = _cube_dimension / 10;
        var _cell_depth:Float = _cube_dimension / 10;
        var offset_x = 2 * _cell_width;
        var offset_y = 2 * _cell_height;
        var offset_z = 2 * _cell_depth;

        var inside_material:StandardMaterial = new StandardMaterial("inside_mat", scene);
        inside_material.backFaceCulling = false;
        inside_material.diffuseColor=new Color3(0,0,1);

        var cellbox:Mesh = MeshBuilder.CreateBox("cell 1", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox.position = new Vector3(
                offset_x,
                offset_y,
                offset_z
        );
        cellbox.material = inside_material;
        cellbox.parent = _cube;

        var cellbox2:Mesh = MeshBuilder.CreateBox("cell 2", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox2.position = new Vector3(
                offset_x + _cell_width,
                offset_y,
                offset_z
        );
        cellbox2.material = inside_material;
        cellbox2.parent = _cube;

        var cellbox3:Mesh = MeshBuilder.CreateBox("cell 3", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox3.position = new Vector3(
                offset_x - _cell_width,
                offset_y,
                offset_z
        );
        cellbox3.material = inside_material;
        cellbox3.parent = _cube;

        var cellbox4:Mesh = MeshBuilder.CreateBox("cell 4", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox4.position = new Vector3(
                offset_x,
                offset_y + _cell_height,
                offset_z
        );
        cellbox4.material = inside_material;
        cellbox4.parent = _cube;

        var cellbox5:Mesh = MeshBuilder.CreateBox("cell 5", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox5.position = new Vector3(
                offset_x,
                offset_y - _cell_height,
                offset_z
        );
        cellbox5.material = inside_material;
        cellbox5.parent = _cube;

        var cellbox6:Mesh = MeshBuilder.CreateBox("cell 6", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox6.position = new Vector3(
                offset_x,
                offset_y,
                offset_z + _cell_depth
        );
        cellbox6.material = inside_material;
        cellbox6.parent = _cube;

        var cellbox7:Mesh = MeshBuilder.CreateBox("cell 7", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox7.position = new Vector3(
                offset_x,
                offset_y,
                offset_z - _cell_depth
        );
        cellbox7.material = inside_material;
        cellbox7.parent = _cube;

        //physics
        var physOpt = new PhysicsBodyCreationOptions();
        physOpt.mass = 0;
        cellbox.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox2.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox3.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox4.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox5.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox6.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox7.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);

    }

    private function rotateCube(axis:Vector3D, angle:Float):Void
    {
        if (animationCount == 0) //allow rotation only if not already one on going
        {
            rotationAxis = new Vector3(axis.x, axis.y, axis.z);
            rotationAngle = angle;
            animationCount = 0;
            stage.addEventListener(Event.ENTER_FRAME, animationRotationHandler);
        }
    }

    private function animationRotationHandler(e:Event):Void 
    {
        animationCount += animationSpeed;
        if (animationCount > 1) { animationCount = 1; }
        _cube.rotate(rotationAxis, rotationAngle*animationSpeed, Space.WORLD);  

        if (animationCount >= 1) 
        {
            animationCount = 0;
            stage.removeEventListener(Event.ENTER_FRAME, animationRotationHandler);
        }
    }

    private function onMouseDown(event:MouseEvent):Void 
    {

        mouse_clicked_start_pos = new Point(event.stageX, event.stageY);
        mouse_clicked_start_time = Lib.getTimer();
    }

    private function onMouseUp(event:MouseEvent):Void 
    {
        if (mouse_clicked_start_time != 0)
        {
            var deltatime:Int = Lib.getTimer() -  mouse_clicked_start_time;
            if (deltatime > 0 && deltatime < 1000)
            {
                var deltaX:Float = mouse_clicked_start_pos.x - event.stageX;
                var deltaY:Float = mouse_clicked_start_pos.y - event.stageY;

                if (Math.abs(deltaX) > Math.abs(deltaY))
                {
                    if (Math.abs(deltaX)>(Lib.current.stage.stageWidth*0.1)) 
                    {
                        if (deltaX > 0) {rotateCube(new Vector3D(0, 1, 0), Math.PI/2);}
                        else {rotateCube(new Vector3D(0, 1, 0), -Math.PI/2); }
                    }   
                }
                else 
                {
                    if (Math.abs(deltaY)>(Lib.current.stage.stageHeight*0.1)) 
                    {
                        if (deltaY > 0) {rotateCube(new Vector3D(1, 0, 0), Math.PI/2);}
                        else {rotateCube(new Vector3D(1, 0, 0), -Math.PI/2); }
                    }   
                }
            }
        }
        mouse_clicked_start_time = 0;

    }

    function resize(e) {
        engine.width = stage.stageWidth;
        engine.height = stage.stageHeight;
    }

    function update(e) {
        engine._renderLoop();
    }

}

Also, if you rotate the shape (by swapping left-right or up-down in the babylonjs example or the babylonHx one), you can see in babylonHx some issue in regions where one box is in front of another. It is like the boxes are kind of transparents whereas they are not supposed to be...

vujadin commented 7 years ago

this probably has to do something with openfl. can you try with lime?

ramsestom commented 7 years ago

Just tried with Lime and it is crashing. Don't know if it is a lime or a babylonHx issue but I won't have time to investigate any further for now (furthermore I am not used to pure lime apps. So I may have done something wrong in my code)

Here is the code of my lime sample if you want to take a look at it:

package;

import lime.app.Application;
import haxe.Timer;
import lime.app.Application;
import lime.Assets;
import lime.audio.AudioSource;
import lime.ui.KeyCode;
import lime.ui.KeyModifier;
import lime.graphics.RenderContext;
import lime.graphics.Renderer;
import lime.ui.Touch;
import lime.ui.Window;
import lime.Lib;

import com.babylonhx.cameras.FreeCamera;
import com.babylonhx.lights.DirectionalLight;
import com.babylonhx.lights.HemisphericLight;
import com.babylonhx.lights.PointLight;
import com.babylonhx.materials.MultiMaterial;
import com.babylonhx.materials.PBRMaterial;
import com.babylonhx.materials.textures.RawTexture;
import com.babylonhx.math.Color3;
import com.babylonhx.mesh.MeshBuilder;
import com.babylonhx.mesh.SubMesh;
import com.babylonhx.mesh.VertexBuffer;
import com.babylonhx.mesh.primitives.Box;
import com.babylonhx.physics.PhysicsBodyCreationOptions;
import com.babylonhx.tools.EventState;
import com.babylonhx.tools.Tools;
import com.babylonhx.utils.Image;
import com.babylonhx.utils.typedarray.UInt8Array;
import com.babylonhx.cameras.ArcRotateCamera;
import com.babylonhx.Engine;
import com.babylonhx.materials.Material;
import com.babylonhx.materials.StandardMaterial;
import com.babylonhx.materials.textures.Texture;
import com.babylonhx.math.Vector3;
import com.babylonhx.math.Space;
import com.babylonhx.mesh.Mesh;
import com.babylonhx.Scene; 
import com.babylonhx.physics.PhysicsEngine;

class Main extends Application {

    private var scene:Scene;
    private var engine:Engine;

    private var mouse_clicked_start_time:Int;
    private var mouse_clicked_start_pos:Array<Int>;

    private var rotationAxis:Vector3;
    private var rotationAngle:Float;
    private var animationSpeed:Float = 0.05; //percent of rotation animation at each frame
    private var animationCount:Float = 0;

    private var _cube:Mesh;
    private var _cube_dimension:Int = 500;

    public function new () {

        super ();

        engine = new Engine(window, true);  
        scene = new Scene(engine);

        engine.width = this.window.width;
        engine.height = this.window.height;

        //Create camera and light
        //var camera = new ArcRotateCamera("Camera", 0, 0, 0, Vector3.Zero(), scene);
        //camera.setPosition(new Vector3(0, 0, -_cube_dimension*2.5));
        //camera.attachControl();

        var camera = new FreeCamera("camera1", new Vector3(0, 0, -20), scene);
        camera.setTarget(Vector3.Zero());

        //var light = new PointLight("Omni", new Vector3( 0, 0, -_cube_dimension * 2.5), scene);
        var light = new PointLight("Omni", new Vector3( 0, 0, -25), scene);

        //create scene objects
        createScene();

        scene.registerBeforeRender(function(scene:Scene, ?es:EventState) {
            light.position = camera.position;
        });

        scene.getEngine().runRenderLoop(function () {
            scene.render();
        });

    }

    private function createScene()
    {
        _cube = new Mesh("cube", scene);
        //createOutsideBox();
        createInsideMesh();
    }

    private function createInsideMesh()
    {
        var _cell_width:Float = 1;// _cube_dimension / 10;
        var _cell_height:Float = 1;// _cube_dimension / 10;
        var _cell_depth:Float = 1;// _cube_dimension / 10;
        var offset_x = 2 * _cell_width;
        var offset_y = 2 * _cell_height;
        var offset_z = 2 * _cell_depth;

        var inside_material:StandardMaterial = new StandardMaterial("inside_mat", scene);
        //inside_material.backFaceCulling = false;
        inside_material.diffuseColor=new Color3(0,0,1);

        var cellbox:Mesh = MeshBuilder.CreateBox("cell 1", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox.position = new Vector3(
                offset_x,
                offset_y,
                offset_z
        );
        cellbox.material = inside_material;
        cellbox.parent = _cube;

        var cellbox2:Mesh = MeshBuilder.CreateBox("cell 2", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox2.position = new Vector3(
                offset_x + _cell_width,
                offset_y,
                offset_z
        );
        cellbox2.material = inside_material;
        cellbox2.parent = _cube;

        var cellbox3:Mesh = MeshBuilder.CreateBox("cell 3", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox3.position = new Vector3(
                offset_x - _cell_width,
                offset_y,
                offset_z
        );
        cellbox3.material = inside_material;
        cellbox3.parent = _cube;

        var cellbox4:Mesh = MeshBuilder.CreateBox("cell 4", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox4.position = new Vector3(
                offset_x,
                offset_y + _cell_height,
                offset_z
        );
        cellbox4.material = inside_material;
        cellbox4.parent = _cube;

        var cellbox5:Mesh = MeshBuilder.CreateBox("cell 5", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox5.position = new Vector3(
                offset_x,
                offset_y - _cell_height,
                offset_z
        );
        cellbox5.material = inside_material;
        cellbox5.parent = _cube;

        var cellbox6:Mesh = MeshBuilder.CreateBox("cell 6", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox6.position = new Vector3(
                offset_x,
                offset_y,
                offset_z + _cell_depth
        );
        cellbox6.material = inside_material;
        cellbox6.parent = _cube;

        var cellbox7:Mesh = MeshBuilder.CreateBox("cell 7", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox7.position = new Vector3(
                offset_x,
                offset_y,
                offset_z - _cell_depth
        );
        cellbox7.material = inside_material;
        cellbox7.parent = _cube;

        //physics
        var physOpt = new PhysicsBodyCreationOptions();
        physOpt.mass = 0;
        cellbox.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox2.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox3.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox4.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox5.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox6.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox7.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);

    }

    /*
    private function rotateCube(axis:Vector3, angle:Float):Void
    {
        if (animationCount == 0) //allow rotation only if not already one on going
        {
            rotationAxis = axis.clone();
            rotationAngle = angle;
            animationCount = 0;
            stage.addEventListener(Event.ENTER_FRAME, animationRotationHandler);
        }
    }

    private function animationRotationHandler(e:Event):Void 
    {
        animationCount += animationSpeed;
        if (animationCount > 1) { animationCount = 1; }
        _cube.rotate(rotationAxis, rotationAngle*animationSpeed, Space.WORLD);  

        if (animationCount >= 1) 
        {
            animationCount = 0;
            stage.removeEventListener(Event.ENTER_FRAME, animationRotationHandler);
        }
    }

    override function onMouseDown(window:Window, x:Float, y:Float, button:Int) 
    {

    mouse_clicked_start_pos = [x, y];
        mouse_clicked_start_time = Lib.getTimer();
    }

    override function onMouseUp(window:Window, x:Float, y:Float, button:Int) 
    {
        if (mouse_clicked_start_time != 0)
        {
            var deltatime:Int = Lib.getTimer() -  mouse_clicked_start_time;
            if (deltatime > 0 && deltatime < 1000)
            {
                var deltaX:Float = mouse_clicked_start_pos.x - x;
                var deltaY:Float = mouse_clicked_start_pos.y - y;

                if (Math.abs(deltaX) > Math.abs(deltaY))
                {
                    if (Math.abs(deltaX)>(Lib.current.stage.stageWidth*0.1)) 
                    {
                        if (deltaX > 0) {rotateCube(new Vector3(0, 1, 0), Math.PI/2);}
                        else {rotateCube(new Vector3(0, 1, 0), -Math.PI/2); }
                    }   
                }
                else 
                {
                    if (Math.abs(deltaY)>(Lib.current.stage.stageHeight*0.1)) 
                    {
                        if (deltaY > 0) {rotateCube(new Vector3(1, 0, 0), Math.PI/2);}
                        else {rotateCube(new Vector3(1, 0, 0), -Math.PI/2); }
                    }   
                }
            }
        }
        mouse_clicked_start_time = 0;

    }

    function resize(e) {
        engine.width = this.window.width;
        engine.height = this.window.height;
    }

    function update(e) {
        engine._renderLoop();
    }
    */

    override public function onWindowResize(window:Window, width:Int, height:Int) {
        engine.width = width;
        engine.height = height;
        engine.resize();
    }

    override function update(deltaTime:Int) {
        #if cpp
        //hxt.advance_frame();
        #end
    }

    override public function render(renderer:Renderer) {
        engine._renderLoop();
    }
}
vujadin commented 7 years ago

you're trying to access window object in constructor. its not yet available at that point, that's why it crashes. you should initialize engine/scene in 'onPreloadComplete' lime event. here's the screenshot of what I'm geting and the fixed code:

test

package;

import lime.app.Application;
import haxe.Timer;
import lime.app.Application;
import lime.Assets;
import lime.audio.AudioSource;
import lime.ui.KeyCode;
import lime.ui.KeyModifier;
import lime.graphics.RenderContext;
import lime.graphics.Renderer;
import lime.ui.Touch;
import lime.ui.Window;
import lime.Lib;

import com.babylonhx.cameras.FreeCamera;
import com.babylonhx.lights.DirectionalLight;
import com.babylonhx.lights.HemisphericLight;
import com.babylonhx.lights.PointLight;
import com.babylonhx.materials.MultiMaterial;
import com.babylonhx.materials.PBRMaterial;
import com.babylonhx.materials.textures.RawTexture;
import com.babylonhx.math.Color3;
import com.babylonhx.mesh.MeshBuilder;
import com.babylonhx.mesh.SubMesh;
import com.babylonhx.mesh.VertexBuffer;
import com.babylonhx.mesh.primitives.Box;
import com.babylonhx.physics.PhysicsBodyCreationOptions;
import com.babylonhx.tools.EventState;
import com.babylonhx.tools.Tools;
import com.babylonhx.utils.Image;
import com.babylonhx.utils.typedarray.UInt8Array;
import com.babylonhx.cameras.ArcRotateCamera;
import com.babylonhx.Engine;
import com.babylonhx.materials.Material;
import com.babylonhx.materials.StandardMaterial;
import com.babylonhx.materials.textures.Texture;
import com.babylonhx.math.Vector3;
import com.babylonhx.math.Space;
import com.babylonhx.mesh.Mesh;
import com.babylonhx.Scene; 
import com.babylonhx.physics.PhysicsEngine;

class Main extends Application {

    private var scene:Scene;
    private var engine:Engine;

    private var mouse_clicked_start_time:Int;
    private var mouse_clicked_start_pos:Array<Int>;

    private var rotationAxis:Vector3;
    private var rotationAngle:Float;
    private var animationSpeed:Float = 0.05; //percent of rotation animation at each frame
    private var animationCount:Float = 0;

    private var _cube:Mesh;
    private var _cube_dimension:Int = 500;

    public function new () {
        super ();
    }

    override public function onPreloadComplete():Void {
        engine = new Engine(window, true);  
        scene = new Scene(engine);

        engine.width = this.window.width;
        engine.height = this.window.height;

        //Create camera and light
        //var camera = new ArcRotateCamera("Camera", 0, 0, 0, Vector3.Zero(), scene);
        //camera.setPosition(new Vector3(0, 0, -_cube_dimension*2.5));
        //camera.attachControl();

        var camera = new FreeCamera("camera1", new Vector3(0, 0, -20), scene);
        camera.setTarget(Vector3.Zero());

        //var light = new PointLight("Omni", new Vector3( 0, 0, -_cube_dimension * 2.5), scene);
        var light = new PointLight("Omni", new Vector3( 0, 0, -25), scene);

        //create scene objects
        createScene();

        scene.registerBeforeRender(function(scene:Scene, ?es:EventState) {
            light.position = camera.position;
        });

        scene.getEngine().runRenderLoop(function () {
            scene.render();
        });
    }

    private function createScene()
    {
        _cube = new Mesh("cube", scene);
        //createOutsideBox();
        createInsideMesh();
    }

    private function createInsideMesh()
    {
        var _cell_width:Float = 1;// _cube_dimension / 10;
        var _cell_height:Float = 1;// _cube_dimension / 10;
        var _cell_depth:Float = 1;// _cube_dimension / 10;
        var offset_x = 2 * _cell_width;
        var offset_y = 2 * _cell_height;
        var offset_z = 2 * _cell_depth;

        var inside_material:StandardMaterial = new StandardMaterial("inside_mat", scene);
        //inside_material.backFaceCulling = false;
        inside_material.diffuseColor=new Color3(0,0,1);

        var cellbox:Mesh = MeshBuilder.CreateBox("cell 1", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox.position = new Vector3(
                offset_x,
                offset_y,
                offset_z
        );
        cellbox.material = inside_material;
        cellbox.parent = _cube;

        var cellbox2:Mesh = MeshBuilder.CreateBox("cell 2", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox2.position = new Vector3(
                offset_x + _cell_width,
                offset_y,
                offset_z
        );
        cellbox2.material = inside_material;
        cellbox2.parent = _cube;

        var cellbox3:Mesh = MeshBuilder.CreateBox("cell 3", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox3.position = new Vector3(
                offset_x - _cell_width,
                offset_y,
                offset_z
        );
        cellbox3.material = inside_material;
        cellbox3.parent = _cube;

        var cellbox4:Mesh = MeshBuilder.CreateBox("cell 4", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox4.position = new Vector3(
                offset_x,
                offset_y + _cell_height,
                offset_z
        );
        cellbox4.material = inside_material;
        cellbox4.parent = _cube;

        var cellbox5:Mesh = MeshBuilder.CreateBox("cell 5", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox5.position = new Vector3(
                offset_x,
                offset_y - _cell_height,
                offset_z
        );
        cellbox5.material = inside_material;
        cellbox5.parent = _cube;

        var cellbox6:Mesh = MeshBuilder.CreateBox("cell 6", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox6.position = new Vector3(
                offset_x,
                offset_y,
                offset_z + _cell_depth
        );
        cellbox6.material = inside_material;
        cellbox6.parent = _cube;

        var cellbox7:Mesh = MeshBuilder.CreateBox("cell 7", {width:_cell_width, height: _cell_height, depth: _cell_depth}, scene);
        cellbox7.position = new Vector3(
                offset_x,
                offset_y,
                offset_z - _cell_depth
        );
        cellbox7.material = inside_material;
        cellbox7.parent = _cube;

        //physics
        var physOpt = new PhysicsBodyCreationOptions();
        physOpt.mass = 0;
        cellbox.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox2.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox3.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox4.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox5.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox6.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);
        cellbox7.setPhysicsState(PhysicsEngine.BoxImpostor, physOpt);

    }

    /*
    private function rotateCube(axis:Vector3, angle:Float):Void
    {
        if (animationCount == 0) //allow rotation only if not already one on going
        {
            rotationAxis = axis.clone();
            rotationAngle = angle;
            animationCount = 0;
            stage.addEventListener(Event.ENTER_FRAME, animationRotationHandler);
        }
    }

    private function animationRotationHandler(e:Event):Void 
    {
        animationCount += animationSpeed;
        if (animationCount > 1) { animationCount = 1; }
        _cube.rotate(rotationAxis, rotationAngle*animationSpeed, Space.WORLD);  

        if (animationCount >= 1) 
        {
            animationCount = 0;
            stage.removeEventListener(Event.ENTER_FRAME, animationRotationHandler);
        }
    }

    override function onMouseDown(window:Window, x:Float, y:Float, button:Int) 
    {

    mouse_clicked_start_pos = [x, y];
        mouse_clicked_start_time = Lib.getTimer();
    }

    override function onMouseUp(window:Window, x:Float, y:Float, button:Int) 
    {
        if (mouse_clicked_start_time != 0)
        {
            var deltatime:Int = Lib.getTimer() -  mouse_clicked_start_time;
            if (deltatime > 0 && deltatime < 1000)
            {
                var deltaX:Float = mouse_clicked_start_pos.x - x;
                var deltaY:Float = mouse_clicked_start_pos.y - y;

                if (Math.abs(deltaX) > Math.abs(deltaY))
                {
                    if (Math.abs(deltaX)>(Lib.current.stage.stageWidth*0.1)) 
                    {
                        if (deltaX > 0) {rotateCube(new Vector3(0, 1, 0), Math.PI/2);}
                        else {rotateCube(new Vector3(0, 1, 0), -Math.PI/2); }
                    }   
                }
                else 
                {
                    if (Math.abs(deltaY)>(Lib.current.stage.stageHeight*0.1)) 
                    {
                        if (deltaY > 0) {rotateCube(new Vector3(1, 0, 0), Math.PI/2);}
                        else {rotateCube(new Vector3(1, 0, 0), -Math.PI/2); }
                    }   
                }
            }
        }
        mouse_clicked_start_time = 0;

    }

    function resize(e) {
        engine.width = this.window.width;
        engine.height = this.window.height;
    }

    function update(e) {
        engine._renderLoop();
    }
    */

    override public function onWindowResize(window:Window, width:Int, height:Int) {
        engine.width = width;
        engine.height = height;
        engine.resize();
    }

    override function update(deltaTime:Int) {
        #if cpp
        //hxt.advance_frame();
        #end
    }

    override public function render(renderer:Renderer) {
        engine._renderLoop();
    }
}
ramsestom commented 7 years ago

OK thanks. I tried with the fixed code on my side and I have the same result as you (the rendering is the one expected. Same as with babylonjs). So you where right. The problem is specific to openfl. Do you know if you can track it down and fix it soon?

Anyway. Isn't openfl supposed to be built on top of lime? So why have a version of babylonHX for openfl and one for lime. Couldn't openfl apps just access the lime lib when necessary for babylonhx? There is probably a good reason for having a different version for both but I am just curious to know it ;)

vujadin commented 7 years ago

For some time it was possible to mix 3D with 2D content on top of it using openfl/nme api which was pretty nice. At some point this stopped working as gl states/shaders/all kinds of stuff started to mix/collide between bhx and openfl and now it produces a lot of bugs/glitches in rendering that it became totally unusable. I don't have time to find out what is going on, I'd have to investigate how openfl rendering pipeline works which would be quite time consuming... Instead I would like to create framework independent 2D API that will work on top of bhx 3D content, and would be integral part of bhx. People at BJS are working on canvas2D but it looks too heavy/complex to me, and I'm not sure about it (although I've done some work in porting it to haxe...). I've ported http://lib.ivank.net/?p=demos to haxe and it works pretty well, its event faster then the original, so maybe I'll try to integrate it with bhx. Or not... maybe I'll go with canvas2D after all. Haven't decided yet

ramsestom commented 7 years ago

OK well I understand. However, developing another 2D API for haxe seems a bit counter productive for me. I mean openfl already have a community, is actively developed and debugged and is well integrated with other useful 2D APIs (like actuate for 2D animations, nape or box2D for physics, starling or haxeui for gui...). By having your own 2D api, you would have developers to get use to it but you are also giving yourself extra work in the future to debug and maintain it correctly... So dropping openfl doesn't seem a good solution for me as it would probably cost you more time and energy to port/develop and maintain another 2D API than having BabylonHx integrated/working with openfl... EDIT: Just looked at the IvanK Lib and it looks pretty similar to the openfl API. It is also inspired from Flash, so porting it from javascript to haxe seems pretty much as reinventing the wheel and making a "clone" of openfl... ;)

Anyway, I still don't really understand why openfl couldn't just work with the lime version of babylonHx rather than having it's specific code. I mean if you changed all #if lime compiler flags into #if lime or openfl (and remove the #if openfl ones ) wouldn't it work just fine (and avoid the necessity to have multiple different implementations to maintain) as openfl integrates lime (so an openfl app have access to the lime API, which is all that babylonHx need to work as it can work with pure lime apps...)?

vujadin commented 7 years ago

The thing is that I want 2D api integrated into BHx and framework independent (that will work with lime/snow/nme like BHx itself does right now - and possibly with kha at some point?!) BHx does work with lime when you use openfl template, after all openfl itself runs on top of lime. All lime api is accessible from openfl app. But openfl is using the same GL context that bhx uses and it all gets messed up... The point is that I have to invest my time in one solution or another: trying to figure out how to fix bhx or openfl to make them work together nicely again and lock/trap bhx to openfl or to try and implement framework independent api. I like second option better because it gives users more choice which is always a good thing. I've already ported IvanK library to lime and it took me just a few days so I just need to 'stick' it to bhx, but I've also done a lot of work in porting bjs canvas2D api to haxe... I just don't have enough free time :( IvanK is based on flash api like openfl but its a lot simpler, there's just a few classes. Its quite simple but provides you with pretty much with all you need I guess. After all, bhx is primarily 3D engine, and I imagine you don't need complete flash/openfl api in 3D game where all you need 2D for is to create some UI (like game menus or HUD). And it will work on lime/snow/nme and probably kha

ramsestom commented 7 years ago

I see you recently added 2D content to BHx. That's great work! I would probably try to port the mini 3D game I had started with openfl and BHx to lime and BHx (as I assume BHx still have issues with openFL). Do you already have a public version of your port of canonjs to haxe that I could use as a 3D physics engine?

vujadin commented 7 years ago

2D is in experimental stage, right now it has pretty big impact on performance... I'm not sure if I will keep it. My cannon port works well with three.js and is quite faster then the original in some cases, but it doesn't work with bhx yet... still have some work to do on it