A Unity 3D script for displaying uncertainty in 3D Reconstructions.

Following up from my latest post, I wanted to share with you one of the solutions I used as part of my MPhil project.

As discussed, a real problem with 3D Reconstruction in archaeology is the subjectivity of the modelling process. While Photogrammetry and Laser Scanning record archaeological features as they are, reconstructions rely on information that is more or less inaccurate. Strothotte et al. (1999) pointed out that uncertainty in Visualisation is caused by imprecision and incompleteness. Site reports tend to present a limited range of data, usually in a 2D format that may not translate to 3D which causes imprecision (Worthing and Counsell 1999). And while interpretation of a site can be built on incomplete information, 3D Reconstruction requires answers to very specific questions that rarely can be answered by the archaeological evidence.

In a bid to display this uncertainty, projects have displayed the model entirely using wireframes or point clouds (Richards 1998). I propose a similar solution: by using a Unity 3D script heavily based on work by Naojitaniguchi (2015), we have different toggles to switch between fully rendered, wireframe and removed. The most uncertain elements are tagged for removal, leaving the more accurate features intact.

Within the scene, the wireframe looks like so:

wireframe

Wireframe 2Wireframe

The Player script initiates the script by attaching it to the objects targeted for removal upon the input of a button:

void RemoveArchaeology(){
		if (Input.GetAxisRaw ("Remove") != 0 && archaeologyRemoved == 0 &&
			removeAxisInUse == false) {
			archaeologyRemoved = 1;
			removeAxisInUse = true;

			foreach (GameObject go in gameObjectArray) {

				go.gameObject.AddComponent ();
			}
		} else if (Input.GetAxisRaw ("Remove") != 0 && archaeologyRemoved == 1 &&
			removeAxisInUse == false) {
			archaeologyRemoved = 2;
			removeAxisInUse = true;

			foreach (GameObject go in gameObjectArray) {

				VertexRenderer vertexRenderer = go.GetComponent ();
				vertexRenderer.RevertToStart ();
				Destroy (vertexRenderer);
				go.SetActive (false);
			}
		}	else if (Input.GetAxisRaw ("Remove") != 0 && archaeologyRemoved == 2 &&
			removeAxisInUse == false){
			archaeologyRemoved = 0;
			removeAxisInUse = true;

			foreach (GameObject go in gameObjectArray) {
				go.SetActive (true);
			}
		}

		if (Input.GetAxisRaw ("Remove") == 0){
			removeAxisInUse = false;
		}
	}

Then, the VertexRenderer script replaces the model with lines:

using UnityEngine;
using System.Collections;

		//Code written by R. P. Barratt
		//robbarratt1@outlook.com
		//
		//Heavily based on a script by Naojitaniguchi (2015).

		//Renders the selected elements as lines.

public class VertexRenderer : MonoBehaviour {

	public Color lineColor;
	public Color backgroundColor;

	private Vector3[] lines;
	private ArrayList linesArray;
	private Material lineMaterial;
	private MeshRenderer meshRenderer;
	private Material initialMaterial;

	public void Start () {

		//Finds the components.
		GetComponent<Renderer> ().enabled = false;
		meshRenderer = GetComponent<MeshRenderer> ();
		if (!meshRenderer) {
			meshRenderer = gameObject.AddComponent<MeshRenderer> ();
		}

		//Saves the initial material.
		SaveInfo ();

		//Finds the line material and sets it.
		Shader shader1 = Shader.Find ("Lines/Background");
		meshRenderer.material = new Material (shader1);
		Shader shader2 = Shader.Find ("Lines/Colored Blended");
		lineMaterial = new Material (shader2);
		lineMaterial.hideFlags = HideFlags.HideAndDontSave;
		lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave; 

		//Creates a list of lines based on the mesh.
		linesArray = new ArrayList ();
		MeshFilter filter = GetComponent<MeshFilter> ();
		Mesh mesh = filter.sharedMesh;
		Vector3[] vertices = mesh.vertices;
		int[] triangles = mesh.triangles; 

		for (int i = 0; i < triangles.Length / 3; i++) {
			linesArray.Add (vertices [triangles [i * 3]]);
			linesArray.Add (vertices [triangles [i * 3 + 1]]);
			linesArray.Add (vertices [triangles [i * 3 + 2]]);
		} 

		lines = new Vector3[triangles.Length];
		for (int i = 0; i < triangles.Length; i++) {
			lines [i] = (Vector3)linesArray [i];
		}

		//Sets material.
		meshRenderer.sharedMaterial.color = backgroundColor;
		lineMaterial.SetPass (0);
	}

	public void OnRenderObject(){

		//Draws lines based on mesh.
		GL.PushMatrix ();
		GL.MultMatrix (transform.localToWorldMatrix);
		GL.Begin (GL.LINES);
		GL.Color (lineColor); 

		for (int i = 0; i < lines.Length / 3; i++) {
			GL.Vertex (lines [i * 3]);
			GL.Vertex (lines [i * 3 + 1]); 

			GL.Vertex (lines [i * 3 + 1]);
			GL.Vertex (lines [i * 3 + 2]); 

			GL.Vertex (lines [i * 3 + 2]);
			GL.Vertex (lines [i * 3]);
		} 

		GL.End ();
		GL.PopMatrix ();
	}

	void SaveInfo(){

		//Saves initial material.
		initialMaterial = meshRenderer.material;
	}

	public void RevertToStart(){

		//Returns to initial material.
		GetComponent<Renderer> ().enabled = true;
		meshRenderer.material = initialMaterial;
	}
}

The script requires Unity3D to run at the moment, but I am sure it can be adapted for other platforms.

The reason for this script is to allow users to choose different options, displaying the finished model with a more realistic skin but also allowing for a more accurate representation.

References:

Naojitaniguchi (2015). WireFrame. Available: https://gist.github.com/naojitaniguchi/862724c55bd322695511. Last accessed 20th Oct 2017.

Richards, J. D. (1998). Recent Trends in Computer Applications in Archaeology. Journal of Archaeological Research Vol.6 No.4 pp.331-382.

Strothotte, T., Masuch, M. and Isenberg, T. (1999). Visualizing Knowledge about Virtual Reconstructions of Ancient Architecture. Computer Graphics International.

Worthing, D. and Counsell, J. (1999). Issues arising from computer-based recording of heritage sites. Structural Survey Vol.17 No.4 pp.200-210.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s