08
Sep

Laser Scan

High resolution laser scan of a brooch found at a Roman Building known as Sladwick, north of Shapwick in Somerset. This model is massively decimated to produce about 5k polys. Click and drag in the window to view the model:

This model was produced by scanning using a Leica laser scanner – 7 scans in all, 4 on the top side, 3 on the reverse. The main issue in scanning this object was the fact that the pin moved between scanning one side and the other. This meant dividing up the point cloud data to separate the pin from the main body.

The flash model viewer was built using Papervision3D and Flex. Code below:


package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import org.papervision3d.view.Viewport3D;
import org.papervision3d.cameras.*;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.parsers.Collada;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.shadematerials.PhongMaterial;
import org.papervision3d.cameras.FrustumCamera3D;

public class Shapwick extends Sprite {

public var viewport:Viewport3D;
public var renderer:BasicRenderEngine;
public var default_scene:Scene3D;
public var camera:FrustumCamera3D;
public var cow:DisplayObject3D;
public var light:PointLight3D;
public var phong:PhongMaterial;
public var redlight:PointLight3D;
public var redphong:PhongMaterial;

private var previousMouseX:Number;
private var previousMouseY:Number;

private var isOribiting:Boolean;
private var cameraPitch:Number = 90;
private var cameraYaw:Number = 270;
private var viewDist:Number = 1000;

public function Shapwick() {
init(500, 400);

}

public function init(vpWidth:Number = 800, vpHeight:Number = 600):void {
initPapervision(vpWidth, vpHeight);
init3d();
initEvents();
}

protected function init3d():void {

var materials:MaterialsList = new MaterialsList();

light = new PointLight3D(true);
light.x = 800; light.y = 800; light.z = 800;
phong = new PhongMaterial(light, 0x228822, 0x002200, 80);
materials.addMaterial( phong, "all" );

//redlight = new PointLight3D(true);
//redlight.x = -800, redlight.y = -800, redlight.z = -800;
//redphong = new PhongMaterial(light, 0xFF0000, 0x220000, 80);
//materials.addMaterial(redphong, "all");

cow = new Collada("http://tel.dur.ac.uk/replicator/3dassets/web5.dae", materials, 0.025);
default_scene.addChild(cow);

camera.lookAt(cow);

}

protected function processFrame():void {
//cow.yaw(1);
}

protected function initPapervision(vpWidth:Number, vpHeight:Number):void {
viewport = new Viewport3D(vpWidth, vpHeight);
addChild(viewport); // Add the viewport to the stage.
renderer = new BasicRenderEngine();
default_scene = new Scene3D();
//default_camera = new Camera3D();
camera = new FrustumCamera3D(viewport, 60, 10, 100000);
}

protected function initEvents():void {
this.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
this.stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
this.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
this.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
this.stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelEvent);
}

protected function onEnterFrame( ThisEvent:Event ):void {
processFrame();
renderer.renderScene(default_scene, camera, viewport);
}

private function onMouseDown(event:MouseEvent):void
{
isOribiting = true;
previousMouseX = event.stageX;
previousMouseY = event.stageY;
}

private function onMouseUp(event:MouseEvent):void
{
isOribiting = false;
}

private function onMouseMove(event:MouseEvent):void
{
var differenceX:Number = event.stageX - previousMouseX;
var differenceY:Number = event.stageY - previousMouseY;

if(isOribiting)
{
cameraPitch -= differenceY * (Math.PI/180);
cameraYaw -= differenceX * (Math.PI/180);

cameraPitch = cameraPitch < 0.001 ? 0.001 : cameraPitch;
cameraPitch = cameraPitch > Math.PI ? Math.PI : cameraPitch;

previousMouseX = event.stageX;
previousMouseY = event.stageY;

camera.orbit(cow, cameraPitch, cameraYaw, viewDist);
}
}

private function onMouseWheelEvent(event:MouseEvent):void
{
viewDist += (event.delta * 50);
camera.orbit(cow, cameraPitch, cameraYaw, viewDist);
}
}

}

The model was opened in Blender for conversion to Collada using the Collada 1.4.0 plugin for Blender 1.49b. The export was for triangles only, disabling physics and using relative paths.