This is G o o g l e's cache of http://www.flashsandy.org/forum/lofiversion/index.php/t365.html as retrieved on 13 Jul 2007 15:59:30 GMT.
G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
The page may have changed since that time. Click here for the current page without highlighting.
This cached page may reference images which are no longer available. Click here for the cached text only.
To link to or bookmark this page, use the following url: http://www.google.com/search?q=cache:EbrK4_Jf-NUJ:www.flashsandy.org/forum/lofiversion/index.php/t365.html+site:www.flashsandy.org/forum&hl=en&ct=clnk&cd=30


Google is neither affiliated with the authors of this page nor responsible for its content.

RJ Vereijken
For some reason I can't get the code for loading external textures to work. The image is loaded into a movieclip, but it won't show up as a skin.

My code
CODE

var skin:Skin;

_root.createEmptyMovieClip("imageholder", _root.getNextHighestDepth());
loadMovie("texture.jpg", "imageholder");

// Set transparent to hide the imageholder on the Stage
_root.imageholder._alpha = 0;

var texture:BitmapData = new BitmapData( _root.imageholder._width, _root.imageholder._height);
texture.draw( _root.imageholder );

skin = new TextureSkin( texture );

//skin = new MixedSkin( 0x00FF00, 100, 0, 100, 1 ); // With this the model displays fine

skin.setLightingEnable( true );

_o.setSkin( skin );
_o.enableBackFaceCulling = true;


If I don't set imageholder's alpha to 0 I can see the image in the movieclip, so it loads fine. This is a modification of the Asetest code by the way, but I want to load an external texture. What am I doing wrong?

Thanks in advance
Petit
QUOTE(RJ Vereijken @ Mar 8 2007, 12:04 PM) *

For some reason I can't get the code for loading external textures to work. The image is loaded into a movieclip, but it won't show up as a skin.


A reason could be, that you draw the imageholder MovieClip to the BitmapData, before the image is loaded.
When you call laodMovie() it will take a while to read the image, but the program continues to execute and the BitmapData is created and the draw() method called.

You should wait for the image to be fully loaded. The texture.draw() method should be called from an event handler. Something like:
CODE
var imageholder:MovieClip = createEmptyMovieClip("imageholder" , getNextHighestDepth());
// Hide images on stage
holder._alpha = 0;
var loader = new MovieClipLoader();
loader.addListener( this );
loader.loadClip("texture.jpg", imageholder );

Here we listen for events from the MovieClipLoader, and when the image is completely loaded, an onLoadInit event is fired. We catch it in the following event handler.
CODE
onLoadInit = function( mc:MovieClip ){
    // Do what ever you must here, for example
    var bitmap:BitmapData = new BitmapData( mc._width, mc._height,true,0x00FFFFFF);
    bitmap.draw( mc );
    var skin:TextureSkin = new TextureSkin( bitmap );
    _o.setSkin( skin );
}

( There may be some typos in the above code, as it is copied and modified on the fly wink.gif)
Attached is a full example, using the Delegate class to give the event handler the correct scope to work in.
QUOTE
[ If you don't know about scope, here's the short version: An event handler may not see ( be able to access ) variables in the code that created the loader. It may only see variables in the class that fired the event ( here the loader ). Using Delegate.create() sets the scope of the event handler to whatever you care to pass to the create() method.]

Here are the FLA Click to view attachment and AS example Click to view attachmentand the external bitmap I use
Click to view attachment
RJ Vereijken
Thanks for your reply. I have modified the code to

CODE

_root.createEmptyMovieClip("imageholder", _root.getNextHighestDepth());
        
// Set transparent to hide the imageholder on the Stage
//_root.imageholder._alpha = 0;

var loader = new MovieClipLoader();
loader.addListener( this );
loader.loadClip("texture.jpg", _root.imageholder );

loader.onLoadInit = function( mc:MovieClip ) {
    var bitmap:BitmapData = new BitmapData( mc._width, mc._height,true,0x00FFFFFF);
    bitmap.draw( mc );
    var skin:TextureSkin = new TextureSkin( bitmap );
    skin.setLightingEnable( true );
    
    _o.setSkin( skin );
    trace("Texture loaded");
}


The function is triggered (proven by the trace) but the model shows up as a wireframe, black lines and no fills. Could this be because the function cannot find the actual object _o in its scope? No idea how to correct it though..

Edit: didn't see that last bit there, working on it now
Petit
QUOTE(RJ Vereijken @ Mar 8 2007, 03:42 PM) *

Could this be because the function cannot find the actual object _o in its scope? No idea how to correct it though..

Yes, it could.
Oki, work on it.
Then if it doesn't work, "no matter what you do", come back here and
attach the complete code ( only the ActionScript required ), and we'll have a look at it.

Good luck!
RJ Vereijken
QUOTE(Petit @ Mar 8 2007, 05:04 PM) *

Yes, it could.
Oki, work on it.
Then if it doesn't work, "no matter what you do", come back here and
attach the complete code ( only the ActionScript required ), and we'll have a look at it.

Good luck!

It works now smile.gif Next step: replacing the active texture at runtime, but I'm saving that for tomorrow.
RJ Vereijken
QUOTE(RJ Vereijken @ Mar 8 2007, 07:08 PM) *

It works now smile.gif Next step: replacing the active texture at runtime, but I'm saving that for tomorrow.


I am now working on being able to change the skin by clicking a button, however I'm running into a problem I can't figure out.

In my root I have an array of filenames for textures. To set a new texture I have added the following function to the AseLoader class

CODE

    public function SetSkin( i ):Void
    {
        loader.loadClip(_root.stofferingen[i], _root.imageholder );
    }


The loader object has already been used to load the first skin (that works) and still has the same function linked to it when the file is loaded by Flash. The problem is that Flash won't let me call my SetSkin function.

When I click a button, I'm executing

CODE

            myMovie.Button.onRelease = function() {
                AseProgram.SetSkin(i);
            }


but this results in

CODE

**Error** Scene=Scene 1, layer=Actions, frame=4:Line 34: The property being referenced does not have the static attribute.
                     AseProgram.SetSkin(i);

Total ActionScript Errors: 1      Reported Errors: 1


If I add the static keyword to the function definition, I get

CODE

**Error** D:\Users\Rudi\Documents\Webroot\ip61\prototype1\AseProgram.as: Line 46: Instance variables cannot be accessed in static functions.
             loader.loadClip(_root.stofferingen[i], _root.imageholder );

Total ActionScript Errors: 1      Reported Errors: 1


How can I get this to work?

Thanks in advance
Petit
QUOTE(RJ Vereijken @ Mar 10 2007, 01:08 PM) *

I am now working on being able to change the skin by clicking a button, however I'm running into a problem I can't figure out.

Well, I guess we'll have to know a little more.
What is the AseLoader class, and why do you want to have a SetSkin method in that class. It sounds like a class loading the objects.
And what is the AseProgram, that also seems to have a SetSkin method?

Formally, your first error comes because you use call AseProgram.SetSkin().
What you say by using the class name, is that the method should be static ( a class method ).
If you have an instance of AseProgram, say program, you could use program.SetSkin().

The second error is thrown because your static method tries to use variables that belong to the instance, which is not allowed.

If your AseProgram is a class, you can create an instance of the class and call methods like this:
CODE
var prog = new AseProgram().
prog.SetSkin(i);
In this case the Setskin method can use instance variables, defined in the AseProgram class.
I'm not sure this will solve your problems, as it is just formal reasoning.
To give more advice, we'll need your code.
You don't have to paste it in the post, you can as well attach it to the post if it is long.
RJ Vereijken
I have gotten it to work. The AseProgram is really the AseTest class from the example, but modified for my schoolproject. At some point (after reading why I got those errors) I tried the very thing you suggested, but Flash would freeze, and I was unable to figure out why.

But now I have moved the code for replacing the skin outside the class, into the main code. Not as elegant as I had hoped, but it works and it's pretty clean.

I have a row of buttons, all containing an image of a new texture that can be applied on the 3D model, and each button has it's own variable i, that tells it which index of the filename-array to use. The onRelease function generated by AS then provides the button with code to create a new skin almost identical to the way described above.

Thanks for all your input =)
Petit
QUOTE(RJ Vereijken @ Mar 10 2007, 04:31 PM) *

I have gotten it to work. The AseProgram is really the AseTest class from the example, but modified for my schoolproject.

Good to hear that you succeeded with your project.
Clean object oriented code is nice, but in Flash this is sometimes troublesome.

Two things can make i painful.
First you cannot create a new MovieClip and only refer to it by a variable. It must always be attached to a parent MovieClip ( _root or other ).

Second, event handlers are are always working in their own scope, which means they normally cant access instance variables and methods in the class ( instance ) that owns the handler. You have to resolve this using delegation, i.e. the Delegate class. At least this problem is solved more elegantly in AS3.

When you have some few images that you want to use as skins, do you read in all images at the start of the application, or do you wait until the user clicks a button?
RJ Vereijken
QUOTE(Petit @ Mar 10 2007, 06:15 PM) *

When you have some few images that you want to use as skins, do you read in all images at the start of the application, or do you wait until the user clicks a button?

Currently I load them when the button is clicked. Though they are relatively small. I am currently using 64x64 (might become bigger), which results in rougly 1 second delay.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2007 Invision Power Services, Inc.