Link to home
Start Free TrialLog in
Avatar of Dreammonkey
DreammonkeyFlag for Belgium

asked on

Papervision3d Scene3D getChildAt method undefined?

I'm working on 3D terrain generator, I'm using papervsion3d 2.0 .

The terrain is built with tiles. The whole terrain is square (4 by 4 tiles)
every tile is a Plane , each Plane is eventually added to the scene;

I now want to trace the Panes in the scene by using the getChildAt method, but this seems to be nonexistent in the Scene3D class. Should I import/extend it? Is there another method for referencing the children in a Scene3d instance?

Your input is highly appreciated !

var viewport:Viewport3D = new Viewport3D(0, 0, true, true);
addChild(viewport);
                        
var renderer:BasicRenderEngine = new BasicRenderEngine();
 
var scene:Scene3D = new Scene3D();
 
var camera:Camera3D = new Camera3D();
camera.zoom = 11;
camera.focus = 50;   
 
var terSize:uint=2;
var kwad:uint=terSize*terSize;
var row:uint=1;
var mam:MovieMaterial;
var cube:Plane;
var tile:earth;
var terArray:Array = new Array();
 
for (var i:uint=0; i<kwad; i++) {
	if (i==terSize*row) {
		row++;
	}
	terArray.push(new earth());
	tile = terArray[i];
		
	mam = new MovieMaterial(tile);
	mam.interactive = true;
	mam.smooth = true;
	mam.animated = true;
		
	cube = new Plane(mam);
	cube.name = "Tile "+i.toString();
	cube.x = (i-(terSize*(row-1)))*200;
	cube.y = 200*(row-1);
	
	cube.addEventListener(MouseEvent.MOUSE_OVER, onTileOver);
	
	function onTileOver(e:Event):void {
		trace(e.currentTarget.name);
		var lookFor:Plane = scene.getChildAt(0); 
//1061: Call to a possibly undefined method getChildAt through a reference with static type org.papervision3d.scenes:Scene3D.
	}
	scene.addChild(cube);
}

Open in new window

SOLUTION
Avatar of Gary Benade
Gary Benade
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Dreammonkey

ASKER

Hi Hobbit, thanks for that input !
I actually need the getChildAt method to work, so I dug into the papervison code and came up with this :

Do you think it's solid?
It seems to be working on my machine...

org.papervision3d.core.proto.SceneObject3D.as :

I added lines 91 - 104 =>

package org.papervision3d.core.proto
{
	import org.papervision3d.Papervision3D;
	import org.papervision3d.core.log.PaperLogger;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.DisplayObject3D;
	
	/**
	* The SceneObject3D class is the base class for all scenes.
	* <p/>
	* A scene is the place where objects are placed, it contains the 3D environment.
	* <p/>
	* The scene manages all objects rendered in Papervision3D. It extends the DisplayObjectContainer3D class to arrange the display objects.
	* <p/>
	* SceneObject3D is an abstract base class; therefore, you cannot call SceneObject3D directly.
	*/
	public class SceneObject3D extends DisplayObjectContainer3D
	{		
		/**
		* Contains a list of DisplayObject3D objects in the scene.
		*/
		public var objects :Array;
	
		/**
		* It contains a list of materials in the scene.
		*/
		public var materials:MaterialsList;
		
		/**
		* The SceneObject3D class lets you create scene classes.
		*
		* @param	container	The Sprite that you draw into when rendering. If not defined, each object must have it's own private container.
		*/
		public function SceneObject3D()
		{
			this.objects = new Array();
			this.materials = new MaterialsList();
	
			PaperLogger.info( Papervision3D.NAME + " " + Papervision3D.VERSION + " (" + Papervision3D.DATE + ")\n" );
 
			this.root = this;
		}
	
		/**
		* Adds a child DisplayObject3D instance to the scene.
		*
		* If you add a GeometryObject3D symbol, a new DisplayObject3D instance is created.
		*
		* [TODO: If you add a child object that already has a different display object container as a parent, the object is removed from the child list of the other display object container.]
		*
		* @param	child	The GeometryObject3D symbol or DisplayObject3D instance to add as a child of the scene.
		* @param	name	An optional name of the child to add or create. If no name is provided, the child name will be used.
		* @return	The DisplayObject3D instance that you have added or created.
		*/
		public override function addChild( child:DisplayObject3D, name:String=null ):DisplayObject3D
		{
			var newChild:DisplayObject3D =	super.addChild( child, name ? name : child.name );
			child.scene = this;
			child.parent = null;
			this.objects.push( newChild );
			return newChild;
		}
	
		/**
		* Removes the specified child DisplayObject3D instance from the child and object list of the scene.
		* </p>
		* [TODO: The parent property of the removed child is set to null, and the object is garbage collected if no other references to the child exist.]
		* </p>
		* The garbage collector is the process by which Flash Player reallocates unused memory space. When a variable or object is no longer actively referenced or stored somewhere, the garbage collector sweeps through and wipes out the memory space it used to occupy if no other references to it exist.
		* </p>
		* @param	child	The DisplayObject3D instance to remove.
		* @return	The DisplayObject3D instance that you pass in the child parameter.
		*/
		public override function removeChild( child:DisplayObject3D ):DisplayObject3D
		{
			super.removeChild( child );
	
			for (var i:int = 0; i < this.objects.length; i++ )
			{
				if (this.objects[i] === child )
				{
					this.objects.splice(i, 1);
					return child;
				}
			}
			return child;
		}
		
		/*dreammonkey's go at getChildAt method*/
		
		public function getChildAt( index:Number ):DisplayObject3D
		{
			//super.getChildAt( index );
	
			for (var i:int = 0; i < this.objects.length; i++ )
			{
				if (i === index )
				{
					
					return this.objects[i];
				}
			}
			return this.objects[i];
		}
				
			
	}
}

Open in new window

Another issue, as long is add the 'MouseEvent.MOUSE_OVER' listener to the plane it works fine,
but when I use 'MouseEvent.CLICK it doesn't, any idea why this is?

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You're right about that, I shall make separate class for it.

Thanks for the code it seems much more solid...

No Luck with the MOUSE_UP listener, I already tried that and MOUSE_DOWN

Could it be the plane is to 'low' so it's underneath the mouse (just a wild guess)
The only change I made is to set :
camera.rotationX = -30;

... but removing this line doesn't solve it...
Any more ideas?
If you like I'll post a new thread...

Thanks !

DM
mmm,... no luck with the class, what am I doing wrong?

I'm importing it in my main movie like this :
import dreammonkey.MySceneObject3D;

PS: how could one throw an exception  ?
I'm rather new to this sort of thing...
package {
	import org.papervision3d.core.proto.SceneObject3D;
 
	class MySceneObject3D extends SceneObject3D {
		public function getChildAt( index:Number ):DisplayObject3D {
			if (index>this.objects.length) {
				return null;
			}// or maybe throw an exception?
			return this.objects[index];
		}
	}
}

Open in new window

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Strange :

line 9 :
super(container);
throws this error :
1137: Incorrect number of arguments.  Expected no more than 0.

What does super actually do?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
small bug, this should be:
                    if ( index >= this.objects.length)
                       throw("Invalid index for getChildAt");
ok thanks again !