Papervision provides a number of useful object parsers for loading 3D models, including the DAE and Collada classes. Ive found the DAE class to work more consistently than the Collada one, so thats how im rolling.
Listening for mouse events on the loaded model should be simple right? Turns out its quite a pain in the arse, as serveral hours of my time, and some googlin has shown. It seems you cannot listen for events on the model itself, but rather you have to loop thru all its materials , and all children of those materials, attaching eventListeners and setting the interactive flag to true.
(NOTE, ensure you also set viewport.interactive = true, and if you want hand cursors viewport.buttonMode = true)
Finally you also need to attach your model to a DisplayObject3D in order to interactive with it within the scene. All too much for my small mind, so a custom class was required, here it is warts n all. Anyone want to refine this – please do!
-
-
package com.vivace.papervision.collada
-
{
-
import flash.events.IOErrorEvent;
-
import flash.events.MouseEvent;
-
-
import org.papervision3d.core.proto.MaterialObject3D;
-
import org.papervision3d.events.FileLoadEvent;
-
import org.papervision3d.events.InteractiveScene3DEvent;
-
import org.papervision3d.objects.DisplayObject3D;
-
import org.papervision3d.objects.parsers.DAE;
-
-
public class InteractiveCollada extends DisplayObject3D
-
{
-
// pass .dae path to constructor
-
public function InteractiveCollada(path:String)
-
{
-
super();
-
-
this.load(path);
-
}
-
-
// [properties] ////////////////////////////////////////////////////////////////////////////////////////////////
-
-
public var model:DAE = new DAE();
-
-
// [events] ////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
private function onFileLoadEvent(event:FileLoadEvent):void
-
{
-
// handle the various events here, im just dealing with the basics – dont be as lazy as me!
-
switch(event.type)
-
{
-
case FileLoadEvent.LOAD_PROGRESS : break;
-
case FileLoadEvent.LOAD_ERROR : tracel(event.message); break;
-
case FileLoadEvent.LOAD_COMPLETE : this.finalizeModel(); break;
-
}
-
}
-
-
private function onIOErrorEvent(event:IOErrorEvent):void
-
{
-
trace(event.text);
-
}
-
-
// ……………………………………………………………………………………………….
-
-
private function onInteractiveEvent(event:InteractiveScene3DEvent):void
-
{
-
// again, being lazy, theres a number of events to handle here, refer to InteractiveScene3DEvent.
-
this.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
-
}
-
-
// [public] ////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
// if its an animated collada……
-
public function play(clip:String = "", loop:Boolean = false):void
-
{
-
this.model.play(clip, loop);
-
}
-
-
// [private] ///////////////////////////////////////////////////////////////////////////////////////////////////
-
-
private function load(path:String):void
-
{
-
this.initEventListeners();
-
this.model.load(path);
-
}
-
-
private function finalizeModel():void
-
{
-
// add model as child
-
this.addChild(this.model);
-
-
// loop thru model to find each material and add interactivity to each mesh.
-
for each(var mat:MaterialObject3D in this.model.materials.materialsByName)
-
{
-
mat.interactive = true;
-
}
-
// then loop thru children recursively adding event listeners
-
this.addInteractiveEventListeners(this.model, InteractiveScene3DEvent.OBJECT_CLICK, this.onInteractiveEvent);
-
}
-
-
private function addInteractiveEventListeners(obj:DisplayObject3D, eventType:String, handler:Function):void
-
{
-
obj.addEventListener(eventType, handler);
-
-
for each(var child:DisplayObject3D in obj.children)
-
{
-
this.addInteractiveEventListeners(child, eventType, handler);
-
}
-
}
-
-
private function initEventListeners():void
-
{
-
this.model.addEventListener(FileLoadEvent.LOAD_PROGRESS, this.onFileLoadEvent);
-
this.model.addEventListener(FileLoadEvent.LOAD_COMPLETE, this.onFileLoadEvent);
-
this.model.addEventListener(FileLoadEvent.LOAD_ERROR, this.onFileLoadEvent);
-
this.model.addEventListener(FileLoadEvent.SECURITY_LOAD_ERROR, this.onFileLoadEvent);
-
this.model.addEventListener(FileLoadEvent.ANIMATIONS_COMPLETE, this.onFileLoadEvent);
-
this.model.addEventListener(FileLoadEvent.ANIMATIONS_PROGRESS, this.onFileLoadEvent);
-
this.model.addEventListener(IOErrorEvent.IO_ERROR, this.onIOErrorEvent);
-
}
-
-
}
-
}

Very useful post, thanks a lot!
Welcome dude. it took me too damn long to suss it out so hoped i could save others the pain!
Hi,
I m trying to figure out whats the use of FileLoadEvent.ANIMATIONS_PROGRESS event. Do u knw when it gets dispatched?
Thanks
Hey Yogesh
i could be wrong, but from memory with animated models, the ANIMATIONS_PROGRESS and ANIMATIONS_COMPLETE events are fired after the actual .dae fil load is complete, some kind of processing of the animation i think. so if you immediately try to play the animation on LOAD_COMPLETE it may fail depending on the size of the .dae…
oh.. I spend much time on this problem.
thanks for useful post.
Thanks buddy, this was super helpful.
yo. slow response, but yeah, glad it helped!