【问题标题】:Papervision3D cube face orientationPapervision3D 立方体面方向
【发布时间】:2011-12-01 03:18:24
【问题描述】:

我有一个关于 Papervision3D 或 bitmapData 的问题,我不确定问题出在哪里。我已经构建了一个程序,它需要 4 个横幅并将它们分成几块,然后将这些块应用于立方体,这样我就可以制作一个横幅旋转器。所以在我运行我的程序后,我有 10 个立方体,每个立方体的 4 个面(正面、顶部、背面、底部)上有一块横幅。问题是某些面的方向不正确(旋转 180 度)。 Papervision3D 中有没有办法旋转立方体面?我认为问题可能出在的另一个地方是,当我创建将应用于立方体面的 bitmapData 时。有没有办法在 bitmapData 创建期间明确定义方向?任何帮助或想法将不胜感激。谢谢!

--------编辑---------

这是我的 CubeMaker.as 类的代码。这是获取图像片段并将它们应用于立方体的类。

package  {

import away3d.events.MaterialEvent;
import away3d.materials.BitmapMaterial;
import away3d.materials.ColorMaterial;
import away3d.materials.TransformBitmapMaterial;
import away3d.primitives.Cube;
import away3d.primitives.data.CubeMaterialsData;
import CubeEvent;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;

public class CubeMaker extends Sprite {

    private var _colorMaterial:ColorMaterial = new ColorMaterial(0x000000);
    private var _dcRef;
    private var _banners:Array;
    private var _cubeArray:Array = [];
    private var _cubeCoung:int = 0;
    private var _numberOfPieces:int;
    private var _width:Number;
    private var _depth:Number;
    private var _height:Number;

    public function CubeMaker(banners:Array, numberOfPieces:int) {

        _dcRef = DocumentClass._base;
        _banners = banners;
        _numberOfPieces = numberOfPieces;
    }

    public function makeCubes() {

        //loop through the cubes
        for (var i = 0; i < _numberOfPieces; i++) {
            var faceBitmapArray:Array;

            //fill array with four faces for current cube
            faceBitmapArray =  fillFace(i);

            //get width and height from a piece instance
            var width:Number;
            var height:Number;
            var tempArray:Array;
            tempArray = _banners[0];
            _width = tempArray[0].width;
            _height = tempArray[0].height;
            _depth = tempArray[0].height;

            //create four materials from bitmapData
            var myFront:TransformBitmapMaterial = new TransformBitmapMaterial(faceBitmapArray[0], {rotation:0} );
            var myTop:TransformBitmapMaterial = new TransformBitmapMaterial(faceBitmapArray[1], {rotation:0.5} );
            var myBack:TransformBitmapMaterial = new TransformBitmapMaterial(faceBitmapArray[2], {rotation:0} );
            var myBottom:TransformBitmapMaterial = new TransformBitmapMaterial(faceBitmapArray[3], {rotation:0} );

            //create two materians from color
            var myLeft:ColorMaterial = new ColorMaterial(0x000000);
            var myRight:ColorMaterial = new ColorMaterial(0x000000);

            //create a CubeMatrialsData from the materials created above
            var myMaterials:CubeMaterialsData = new CubeMaterialsData( { front:myFront, back:myBack, top:myTop, bottom:myBottom, left:myLeft, right:myRight} );

            //listen for material change
            myMaterials.addOnMaterialChange(materialChanged);

            //create a new cube with the CubeMaterialsData created earlier
            var _cube = new Cube({width:_width, height:_height, depth:_depth, cubeMaterials:myMaterials}); 

            //the created cube is put into the _cubeArray
            _cubeArray[i] = _cube;
            if (i == (_numberOfPieces - 1)) cubesMade();
        }
    }
    private function fillFace(i:int):Array {
        var faceBitmapArray:Array = [];
        for (var j = 0; j < 4; j++) {
            //tempBannerArray filled with one banner in pieces
            var tempBannerArray:Array = _banners[j];
            //batmapData created and sized to current banner piece
            var bitmapData:BitmapData = new BitmapData(tempBannerArray[i].width, tempBannerArray[i].height);
            //bitmapData filled with current banner piece bitmap data
            bitmapData = tempBannerArray[i].bitmapData;
            bitmapData.lock();

            //array is filled with bitmap data
            faceBitmapArray[j] = bitmapData;
        }
        return faceBitmapArray;
    }

    private function cubesMade() {
        //dispatch event to notify of cube making completion
        dispatchEvent(new CubeEvent(CubeEvent.CUBES_MADE, _cubeArray.length));
    }

    private function materialChanged(e:MaterialEvent):void {
        trace("Warning! Warning! Material changed!");
    }

    public function get cubes():Array {
        return _cubeArray;
    }

    public function get cubeWidth():Number {
        return _width;
    }

    public function get cubeHeight():Number {
        return _height;
    }

    public function get cubeDepth():Number {
        return _depth;
    }
}   

}

【问题讨论】:

    标签: actionscript-3 papervision3d


    【解决方案1】:

    前言:Papervision3D is close to unsupported / closed as a library,所以我强烈推荐使用Away3D 或其他actionscript 3D 库。尽管在 PV3D 上所做的工作是从 Flash 的角度来看是突破性的和令人难以置信的,但如果您希望使用它构建 3D 体验,那么它非常好。从一开始就知道未来的开发者+支持不太可能。

    撇开序言,看一下库中的“Cube”原始类。您可以创建材质并将它们附加到将添加到多维数据集实例的 MaterialsList 实例。假设您使用的是 BitmapMaterial,它有一个可以设置的“旋转”属性。只需确定哪些材料倒置并使其旋转 = 180。优点:快速;缺点:硬编码。

    另一种选择是在“资产”端解决问题并翻转图像。优点:快;缺点:不可扩展或将问题交给设计师。

    在加载数据/资产时,最好的选择是拥有一个“旋转”属性,您可以使用该属性来设置应翻转哪些图像。它是一个立方体,就像安德说的那样,向上是相对的。

    【讨论】:

    • 感谢所有伟大的洞察力!我认为要解决的第一个问题是切换 3D 库。似乎这可能是 Papervision 的问题。这是一个奇怪的问题,因为它只是在横幅的任何给定一侧翻转的部分碎片,而不是整个横幅。所以翻转艺术品是不够的。我会考虑使用 Away3D,也许这会有所帮助。
    • 祝你好运。如果您在横幅拆分上发布您的逻辑,它可能与此有关。
    • 谢谢。我很确定实际的横幅分割很好。原因是当我编写该逻辑时,我编写了一个类以在舞台上以 2D 形式显示这些片段,并且效果很好。只有当他们开始合并 Papervision3D 类时,他们才开始好转。
    • 好吧,我将我的应用程序切换到了 Away3D,渲染速度更快,这很好。但是,材质显示更糟糕,现在有些碎片单向旋转 90,另一些旋转 90,有些旋转 180。我想我可能需要逻辑来判断图像的方向,也许是一排白色像素我在渲染之前就切断了,或者类似的东西。
    • 很高兴 Away3D 工作,需要一些时间来适应。发布您的代码;也许我们可以弄清楚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多