ianharrigan / haxeui

IMPORTANT NOTE! This repository is no longer maintained. Please consider the newer version: https://github.com/haxeui/haxeui-core
http://haxeui.org/
392 stars 47 forks source link

Compounded 3D transforms cause flicker #210

Open Type1J opened 9 years ago

Type1J commented 9 years ago

OpenFL technically doesn't have 3D transforms yet in native and html5, but in Flash compound transforms work correctly, but cause some objects to flicker, and some to ignore their transform in some ways.

I don't know if this may be a bug in Flash, or it may happen as a result of the way HaxeUI draws; I'm not sure, but I'm hoping that it's the latter because that would mean that it's fixable.

To see what I'm talking about, use the following:

package;

import haxe.ui.toolkit.core.Toolkit;
import haxe.ui.toolkit.controls.Button;
import haxe.ui.toolkit.core.Macros;
import haxe.ui.toolkit.core.Root;
import haxe.ui.toolkit.events.UIEvent;
import haxe.ui.toolkit.themes.GradientTheme;
import haxe.ui.toolkit.containers.VBox;
import haxe.ui.toolkit.containers.ScrollView;
import motion.easing.Elastic;
import motion.Actuate;

class Main {
    public static function main() {
        Toolkit.theme = new GradientTheme();
        Toolkit.init();

        Toolkit.openPopup({x: 410, width: 370, height: 560}, function(root:Root) {
            var rotated = false;
            var flat_params = {
                rotationY: root.sprite.rotationY,
                x: root.sprite.x,
                z: root.sprite.z
            };
            var rotated_params = {
                rotationY: flat_params.rotationY + 45,
                x: flat_params.x + 60,
                z: flat_params.z + 250
            };
            var rotate = function(event:UIEvent) {
                if (rotated) {
                    Actuate.tween(root.sprite, 0.8, flat_params)
                        .ease(Elastic.easeOut);
                } else {
                    Actuate.tween(root.sprite, 0.8, rotated_params)
                        .ease(Elastic.easeOut);
                }
                rotated = !rotated;
            }

            var view = new ScrollView();
            view.x = 10;
            view.y = 10;
            view.width = 350;
            view.height = 200;
            var vbox = new VBox();
            view.addChild(vbox);
            root.addChild(view);

            var newButton = function(i:Int) {
                var button = new Button();
                //button.sprite.rotationX = 30; // The problem occurs if this line is uncommented.
                button.text = 'Root 3 $i';
                button.onClick = rotate;
                return button;
            }
            for (i in 0...30) {
                vbox.addChild(newButton(i));
            }
        });
    }
}

The above code should run correctly. When you click any of the buttons, the panel will fall back in a 3D slant. Click any button again, and it restores itself. This is only 1 3D tranform. (Yes, the mouse coordinates are reported correctly to the buttons because they are transformed as well.)

To add a second 3D transform, uncomment the following line (53, I think):

//button.sprite.rotationX = 30; // The problem occurs if this line is uncommented.

This will tilt all of the buttons toward the screen from their bottom. The tilt is correctly displayed, but the scroll area has problems that it didn't before, and the buttons flicker for some reason. Also, the root component doesn't rotate, it just descends, but the scrollview does rotate and display in the correct location.

I realize that this may be a fringe use, but I want to use this everywhere in games, even if I can only get the 1 3D transform, it looks much better than keeping everything flat, which is why I'm going to try to make it work on native and html5 if this issue can be resolved for Flash.

ianharrigan commented 9 years ago

Very cool stuff... I havent run the code, but will at some point today... as you said, hopefully its an issue with haxeui drawing as thats a simple fix. Ill check it out. If i can reproduce it might be worth create a non haxeui project and see what happens there, either way, i really like the idea of this feature.

Cheers, Ian

ianharrigan commented 9 years ago

I get all kinds of strangness with the line button.sprite.rotationX = 30 uncommented:

This happens when i mouse over things (ie, all the buttons dissapear): ss01

And this happens when i click it ss02

Ill take a look, the mouse over thing certainly seems like its going to be haxeui related.

ianharrigan commented 9 years ago

Goes away when i set <set name="haxeui-filters-off" /> in application.xml, but then when it rotates on click the scroll view stops clipping. So the problem seems two fold: something with the filters and something with the clip rect. Stil, very cool thing. Ill add another log to be able to use these properties without going through Component.sprite. So you can do Component.rotationX as well as use them in xml and styles.

ss03 ss04

ianharrigan commented 9 years ago

Not sure how much time ill get over the weekend though im afraid...

Type1J commented 9 years ago

Remember that for the time being that openfl.display.Sprite doesn't have these properties for native and html5, so a

#if flash
    ...
#end

is needed. I did open an issue on OpenFL about the properties not being there for native and html5. The newer draw code for OpenFL 3 (openfl_next) should be able to support them.

ianharrigan commented 9 years ago

Cool, well, i expose them always to the component, they just wont do anything for non flash builds (just so xml and styles wont break). Very cool little feature, never thought about it before.

Going to have a lot of fun/headaches with these three props! :)

Type1J commented 9 years ago

Four props :-) See https://github.com/ianharrigan/haxeui/issues/211

ianharrigan commented 9 years ago

So it does work without compounding transforms. (scroll rect and shadows i mean), another thing ive noticed (without the compound transform) is click and drag on the scroll bar behaves badly as its clearly not taking in the transform into effect so the x/y of the down isnt right. So there will have to be some type of way to calculate that.

ss05

ianharrigan commented 9 years ago

and btw, if you have any hints, pointers, info - just in flash, nothing to do with haxeui - of how scrollrect should behave with compound 3d transforms then that would be amazing. Im fairly sure its all scrollrecrt related

Type1J commented 9 years ago

You could mask, but it looks bad, and it's not the most efficient thing to do.

What's better is to just have them pop in and out of existence at the ends. Of course, you might want to have them fade in and out of existence instead of pop that could be done by sending an event to each item with a 0.0 to 1.0 value of where it is in the visible part of the scrolled content (clamp to 0.0 and 1.0, when it's not visible, and maybe not even send the event). That would let it update it's own values to appear and disappear as it sees fit.

I don't think that anything in haxeui currently behaves that way, but I think Qt does something like that with it's QML ListView and PathView.

The other big UI people that may give good ideas for what to do here would be famo.us