Away3d aplying texture/ matterial issues - actionscript-3

Hello i try to texture a sphere with a png but it apply the texture wrong and messes it up.
i cant find any way to move it around and play with the texture/material untill it will be set correctly.
i want to create a soccer ball and to apply it a ball texture
This is my code i use to create the material and apply it
Thanks
[Embed(source=”../assets/Ball.png”)]
public static var TheBallTextureClass:Class;
public var TheBallMaterial:TextureMaterial;
var theball:Mesh;
TheBallTexture = new BitmapTexture(new TheBallTextureClass().bitmapData);
TheBallMaterial = new TextureMaterial(Cast.bitmapTexture(TheBallTexture));
TheBallMaterial.smooth = true;
TheBallMaterial.repeat = true;
theball = new Mesh(new SphereGeometry(30), _ballMaterial);

That's because the UV Mapping of the SphereGeometry is weird and is not made for a pattern like the soccer ball.
I suggest you to create the sphere in 3ds max and unwrap it there.
EDIT:
If you want you can edit UV mapping of SphereGeometry inside Away3D:
Create a SubClass of SphereGeometry and override "buildUVs(target:CompactSubGeometry)" creating your own set of UVs.

Related

Collision detection kit with FlashPunk

I start creating my flash game using Flashpunk, for collisions i didn't want to use hitboxes because i had images (PNG) with transparent parts in them so i decided to use Collision Detection Kit, i have a problem when creating the collision list, it takes a display object as a parameter and doesn't accept flash punk spritemaps, i tried to cast the spritemap to a flash display object but it's not working, is there a way to use the CDK with flashpunk ?
override public function begin():void
{
_player = new Player(100, 100);// Entity
initCollision(_player.sprPlayer);// The Entity Spritemap
}
private function initCollision(player:Spritemap):void {
collisionChecker = new CollisionList(player); // Problem here
}
Well, you could create an empty BitmapData with the same width & height of your Spritemap and then "render" it to that BitmapData, like so:
var bmd:BitmapData = new BitmapData(64, 64, true, 0);
var sprite:Spritemap = _player.sprPlayer;
sprite.render(bmd, new Point(0,0), new Point(0,0));
collisionChecker = new CollisionList(bmd);
That should draw the spritemap's current frame to a BitmapData which you could then use for the CollisionList. The code above is an example that only demonstrates how to do this. For your actual code, it would be better to avoid constantly initializing new variables during your collision detection.

How can I move bones of a loaded asset programmatically in Away3D?

I'm loading a 3D asset into a Away3D scene and I'd like to move the position of the bones in code.
The asset loading all goes well, I grab a pointer to the Mesh and Skeleton while loading:
private function onAssetComplete(evt:AssetEvent):void
{
if(evt.asset.assetType == AssetType.SKELETON){
_skeleton = evt.asset as Skeleton;
} else if (evt.asset.assetType == AssetType.MESH) {
_mesh = evt.asset as Mesh;
}
}
After the asset(s) have finished loading, I have a valid Skeleton and Mesh instance, the model is also visible in my scene. The next thing I tried is the following.
// create a matrix with the desired joint (bone) position
var pos:Matrix3D = new Matrix3D();
pos.position = new Vector3D(60, 0, 0);
pos.invert();
// get the joint I'd like to modifiy. The bone is named "left"
var joint:SkeletonJoint = _skeleton.jointFromName("left");
// assign joint position
joint.inverseBindPose = pos.rawData;
This code runs without error, but the new position isn't being applied to the visible geometry, eg. the position of the bone doesn't change at all.
Is there an additional step I'm missing here? Do I have to re-assign the skeleton to the Mesh somehow? Or do I have to explicitly tell the mesh that the bone positions have changed?
This might not be the best way to solve this, but here's what I figured out:
Away3D only applies joint transformations to the geometry when an animation is present. In order to apply your transforms, your geometry must have an animation or you'll have to create an animation in code. Here's how you do that (preferably in your LoaderEvent.RESOURCE_COMPLETE handler method:
// create a new pose for the skeleton
var rootPose:SkeletonPose = new SkeletonPose();
// add all the joints to the pose
// the _skeleton member is being assigned during the loading phase where you
// look for AssetType.SKELETON inside a AssetEvent.ASSET_COMPLETE listener
for each(var joint:SkeletonJoint in _skeleton.joints){
var m:Matrix3D = new Matrix3D(joint.inverseBindPose);
m.invert();
var p:JointPose = new JointPose();
p.translation = m.transformVector(p.translation);
p.orientation.fromMatrix(m);
rootPose.jointPoses.push(p);
}
// create idle animation clip by adding the root pose twice
var clip:SkeletonClipNode = new SkeletonClipNode();
clip.addFrame(rootPose, 1000);
clip.addFrame(rootPose, 1000);
clip.name = "idle";
// build animation set
var animSet:SkeletonAnimationSet = new SkeletonAnimationSet(3);
animSet.addAnimation(clip);
// setup animator with set and skeleton
var animator:SkeletonAnimator = new SkeletonAnimator(animSet, _skeleton);
// assign the newly created animator to your Mesh.
// This example assumes that you grabbed the pointer to _myMesh during the
// asset loading stage (by looking for AssetType.MESH)
_myMesh.animator = animator;
// run the animation
animator.play("idle");
// it's best to keep a member that points to your pose for
// further modification
_myPose = rootPose;
After that initialization step, you can modify your joint poses dynamically (you alter the position by modifying the translation property and the rotation by altering the orientation property). Example:
_myPose.jointPoses[2].translation.x = 100;
If you don't know the indices of your joints and rather address bones by name, this should work:
var jointIndex:int = _skeleton.jointIndexFromName("myBoneName");
_myPose.jointPoses[jointIndex].translation.y = 10;
If you use the name-lookup frequently (say every frame) and you have a lot of bones in your model, it's advisable to build a Dictionary where you can look up bone indices by name. The reason for this is that the implementation of jointIndexFromName performs a linear search through all joints which is wasteful if you do this multiple times.

AS#3 changing material Textures

I cant seem to find a solution, anyways basically im trying to add a new dynamic texture to a 3D model using Away3d engine with flash
var myImage:BitmapData = new BitmapData(256, 256, true,0xFFFFFFFF);
// i cant seem to reference this to my 3D model in the example: Myevent(enter frame):
myModel.material = new TextureMaterial(new BitmapTexture(myImage))
I have tried different things along the above method, i have checked the away3d docs and cant find something similar for my current situation:
Im using the latest Away3d lib, and flash player 11...all my models works and load with there original embedded materialtTextures, im just trying to change them to a bitmap or texture that i have dynamically created
Take a look here:
https://github.com/away3d/away3d-tutorials-fp11/blob/master/tutorials/materials/basic_shading/src/Basic_Shading.as
They use Away3D’s Cast utility class to create BitmapTexture objects and they also add a bunch of different texture maps - hopefully this helps
** EDIT --- This Tutorial Does Work **
Added
public bmt:BtiMapTexture;
....
private function initMaterials():void {
this.bmt = new BitmapTexture(new BitmapData(256,256, true, 0x222277FF));
sphereMaterial = new TextureMaterial(Cast.bitmapTexture(this.bmt));
sphereMaterial.specularMap = Cast.bitmapTexture(this.bmt);
sphereMaterial.lightPicker = lightPicker;
}
And I got a nice blue sphere
My solution is:
var mesh:Mesh = 'the mesh for changing'
for each (var item:SubMesh in mesh.subMeshes) {
item.material = null;
}
mesh.material = new ColorMaterial(0xFF00FF);

Create a MovieClip out of another object

In my Actionscript program, I draw a polygon using the methods:
this.graphics.moveTo()
and
this.graphics.lineTo()
In the update function of the polygon model I change it a bit, and then draw it all over again. Eventually, every call to the update() function draws the updated polygon and I can see it changes.
On some point of the program, I want to be able to use this polygon as a movieclip, so I
can attach a mask to it - so as the polygon drawn over and over again, I could see a nice
background in the form of that polygon, fills it inside.
Problem is - I do not know how to take this array of points I have, which is my polygon representation, and turn it into a movieclip ( if possible at all... )
If you have any other recommendations how to implement the above, It would be great.
You can just create a new MovieClip and use it's graphics for drawing. So instead of using this.graphics.moveTo / lineTo, try this:
var mc:MovieClip = new MovieClip();
mc.graphics.moveTo(...);
mc.graphics.lineTo(...);
this.addChild(mc);
A convenient way of drawing, if you want to type less, is to do something like this:
var mc:MovieClip = new MovieClip();
with(mc.graphics) {
clear();
lineStyle(...);
moveTo(...);
lineTo(...);
...
ect.
}
this.addChild(mc);
I suggest you take a look at Point class. For example,
var p1:Point = new Point(100,150);
Then you can have an array of points
var arrPoints:Array = new Array(p1,p2,p3);
With a for loop, you can decide if i==0 you use moveTo and for the rest use lineTo. You can have a special condition at the end to close your polygon, i==arrPoints.length-1.
So, basically create a movieclip object, use its graphic property to fill it with the points you defined in your array. As long as your points are in a movieclip, you can mask it. Finally, that "this" notation you used is probably referring to the main movieclip which is the stage.
var mc:MovieClip = new MovieClip();
mc.graphics.moveTo(p1.x,p1.y);
will draw your graphics into your mc.

How can I load a Papervision/Flex application (SWF) as a material on a Papervision plane?

I am trying to build a portfolio application similar to the used by Whitevoid. I am using Flex 4 and Papervision3D 2. I have everything working except for one issue. When I try to load an external SWF as a material on one of the planes, I can see any native Flex or Flash components in their correct positions, but the papervision objects are not being rendered properly. It looks like the viewport is not being set in the nested swf. I have posted my code for loading the swf below.
private function loadMovie(path:String=""):void
{
loader = new Loader();
request = new URLRequest(path);
loader.contentLoaderInfo.addEventListener(Event.INIT, addMaterial);
loader.load(request);
}
private function addMaterial(e:Event):void
{
movie = new MovieClip();
movie.addChild(e.target.content);
var width:Number = 0;
var height:Number = 0;
width = loader.contentLoaderInfo.width;
height = loader.contentLoaderInfo.height;
//calculate the aspect ratio of the swf
var matAR:Number = width/height;
if (matAR > aspectRatio)
{
plane.scaleY = aspectRatio / matAR;
}
else if (matAR < aspectRatio)
{
plane.scaleX = matAR / aspectRatio;
}
var mat:MovieMaterial = new MovieMaterial(movie, false, true, false, new Rectangle(0, 0, width, height));
mat.interactive = true;
mat.smooth = true;
plane.material = mat;
}
Below I have posted two pictures. The first is a shot of the application running by itself. The second is the application as a MovieMaterial on a Plane. You can see how the button created as a spark object in the mxml stays in the correct position, but papervision sphere (which is rotating) is in the wrong location. Is there something I am missing here?
Man. I haven't seen that site in a while. Still one of the cooler PV projects...
What do you mean by:
I cannot properly see the scene rendered in Papervision
You say you can see the components in their appropriate positions, as in: you have a plane with what looks like the intended file loading up? But I'm guessing that you can't interact with it.
As far as I know, and I've spent a reasonable amount of time trying to make something similar work, the MovieMaterial (which I assume you're using) draws a Bitmap of whatever contents exist in your MovieClip, and if you set it to animated=true, then it will render out a series of bitmaps - equating animation. What it's not doing, is displaying an actual MovieClip (or SWF) on the plane. So you may see your components, but this is how:
MovieMaterial.as line 137
// ______________________________________________________________________ CREATE BITMAP
/**
*
* #param asset
* #return
*/
protected function createBitmapFromSprite( asset:DisplayObject ):BitmapData
{
// Set the new movie reference
movie = asset;
// initialize the bitmap since it's new
initBitmap( movie );
// Draw
drawBitmap();
// Call super.createBitmap to centralize the bitmap specific code.
// Here only MovieClip specific code, all bitmap code (maxUVs, AUTO_MIP_MAP, correctBitmap) in BitmapMaterial.
bitmap = super.createBitmap( bitmap );
return bitmap;
}
Note in the WhiteVoid you never actually interact with a movie until it "lands" = he's very likely swapping in a Movie on top of the bitmap textured plane.
The part that you are interacting with is probably another plane that holds the "button" that simply becomes visible on mouseover.
I think PV1.0 had access to real swfs as a material but this changed in 2.0. Sadly. Hopefully Molehill will.
cheers