MaxstARSDK  3.5.0
AbstractMapViewerBehaviour.cs
1 /*==============================================================================
2 Copyright 2017 Maxst, Inc. All Rights Reserved.
3 ==============================================================================*/
4 
5 using UnityEngine;
6 using System.Text;
7 using JsonFx.Json;
8 using System;
9 using System.Runtime.InteropServices;
10 
11 namespace maxstAR
12 {
16  public abstract class AbstractMapViewerBehaviour : MonoBehaviour
17  {
18  [SerializeField]
19  private int keyframeIndex = 0;
23  public int KeyframeIndex
24  {
25  get { return keyframeIndex; }
26  set
27  {
28  keyframeIndex = value;
30  }
31  }
32 
33  [SerializeField]
34  private bool showMesh = false;
38  public bool ShowMesh
39  {
40  get { return showMesh; }
41  set
42  {
43  showMesh = value;
45  }
46  }
47 
48  [SerializeField]
49  private bool autoCamera = false;
53  public bool AutoCamera
54  {
55  get { return autoCamera; }
56  set
57  {
58  autoCamera = value;
60  }
61  }
62 
63  [SerializeField]
64  private int maxKeyframeCount = 0;
68  public int MaxKeyframeCount
69  {
70  get { return maxKeyframeCount; }
71  set { maxKeyframeCount = value; }
72  }
73 
74  [SerializeField]
75  private bool transparent = false;
79  public bool Transparent
80  {
81  get { return transparent; }
82  set
83  {
84  transparent = value;
86 
87  SetTransparent(transparent);
88  }
89  }
90 
91  [SerializeField]
92  private Quaternion[] cameraRotations = null;
93 
94  [SerializeField]
95  private Matrix4x4[] cameraMatrices = null;
96 
97  [SerializeField]
98  private Vector3[] vertices = null;
99 
100  [SerializeField]
101  private Material[] materials = null;
102 
103  [SerializeField]
104  private MapRendererBehaviour mapRendererBehaviour = null;
105 
111  public bool Load(string fileName)
112  {
113  if (!ReadMap(fileName))
114  {
115  return false;
116  }
117 
118  Debug.Log("Read Json Success");
119 
120  mapRendererBehaviour = gameObject.GetComponent<MapRendererBehaviour>();
121  if (mapRendererBehaviour == null)
122  {
123  mapRendererBehaviour = gameObject.AddComponent<MapRendererBehaviour>();
124  }
125 
126  mapRendererBehaviour.Clear();
127  mapRendererBehaviour.Create(vertices, cameraMatrices, materials);
128 
129  SetTransparent(transparent);
130  UpdateMapViewer();
131 
132  return true;
133  }
134 
135  private bool ReadMap(string fileName)
136  {
137  MapViewer.GetInstance().Deinitialize();
138  if (!MapViewer.GetInstance().Initialize(fileName))
139  {
140  return false;
141  }
142 
143  IntPtr jsonPtr = MapViewer.GetInstance().GetJson();
144  string json = Marshal.PtrToStringAnsi(jsonPtr);
145 
146  if (json.Length < 1)
147  {
148  Debug.Log("Map is not opened");
149  return false;
150  }
151 
152  Map3D map3D = JsonReader.Deserialize<Map3D>(json);
153 
154  int width = map3D.width;
155  int height = map3D.height;
156  maxKeyframeCount = map3D.imageCount;
157 
158  vertices = new Vector3[map3D.vertexCount];
159  for (int i = 0; i < map3D.vertexCount; i++)
160  {
161  vertices[i] = new Vector3(map3D.vertices[i].x, -map3D.vertices[i].y, map3D.vertices[i].z);
162  }
163 
164  cameraMatrices = new Matrix4x4[maxKeyframeCount];
165  for (int i = 0; i < maxKeyframeCount; i++)
166  {
167  for (int j = 0; j < 16; j++)
168  {
169  cameraMatrices[i][j] = map3D.poseMatrices[i][j];
170  }
171  cameraMatrices[i] = cameraMatrices[i].inverse;
172  }
173 
174  cameraRotations = new Quaternion[maxKeyframeCount];
175  for (int i = 0; i < maxKeyframeCount; i++)
176  {
177  cameraRotations[i] = MatrixUtils.InvQuaternionFromMatrix(cameraMatrices[i]);
178  Vector3 tempR = cameraRotations[i].eulerAngles;
179  tempR.x = -tempR.x;
180  tempR.y = -tempR.y;
181  cameraRotations[i] = Quaternion.Euler(tempR);
182  }
183 
184  Shader color = Shader.Find("Unlit/Texture");
185  materials = new Material[maxKeyframeCount];
186  for (int i = 0; i < maxKeyframeCount; i++)
187  {
188  materials[i] = new Material(color);
189  materials[i].mainTexture = GetCameraTexture(i, width, height);
190  }
191 
192  return true;
193  }
194 
195  private void SetTransparent(bool transparent)
196  {
197  if (materials == null)
198  {
199  return;
200  }
201 
202  Shader alpha = Shader.Find("Unlit/Transparent");
203  Shader color = Shader.Find("Unlit/Texture");
204 
205  int materialsLength = materials.Length;
206  for (int i = 0; i < materialsLength; i++)
207  {
208  if (transparent == true)
209  {
210  materials[i].shader = alpha;
211  }
212  else
213  {
214  materials[i].shader = color;
215  }
216  }
217  }
218 
219  private Texture2D GetCameraTexture(int index, int width, int height)
220  {
221  int size = width * height;
222  byte[] image = new byte[size];
223  MapViewer.GetInstance().GetImage(index, out image[0]);
224 
225  byte alpha = 127;
226  byte[] rawTextureData = new byte[size * 4];
227  for (int j = 0; j < size; j++)
228  {
229  rawTextureData[j * 4 + 0] = alpha;
230  rawTextureData[j * 4 + 1] = image[j];
231  rawTextureData[j * 4 + 2] = image[j];
232  rawTextureData[j * 4 + 3] = image[j];
233  }
234 
235  Texture2D texture = new Texture2D(width, height, TextureFormat.ARGB32, false);
236  texture.LoadRawTextureData(rawTextureData);
237  texture.Apply();
238 
239  return texture;
240  }
241 
245  public void UpdateMapViewer()
246  {
247  if (showMesh == true)
248  {
249  mapRendererBehaviour.SetDeactiveImageObjects();
250  mapRendererBehaviour.SetActiveMeshObject(keyframeIndex);
251  }
252  else
253  {
254  mapRendererBehaviour.SetDeactiveMeshObjects();
255  mapRendererBehaviour.SetActiveImageObject(keyframeIndex);
256  }
257  }
258 
264  public void ApplyViewCamera(Vector3 position, Quaternion quaternion)
265  {
266  const float distanceWeight = 1.0f;
267  const float angleWeight = 10.0f;
268 
269  float minWeightSum = 999999.0f;
270 
271  Vector3 tPosition = position;
272  Quaternion tQuaternion = quaternion;
273 
274  for (int i = 0; i < maxKeyframeCount; i++)
275  {
276  Matrix4x4 cameraMatrix = cameraMatrices[i];
277  Vector3 cameraPosition = new Vector3(cameraMatrix.m03, cameraMatrix.m13, cameraMatrix.m23);
278 
279  float calcDistance = Vector3.Distance(tPosition, cameraPosition);
280  float calcAngle = Quaternion.Angle(tQuaternion, cameraRotations[i]);
281  float calcWeightSum = distanceWeight * calcDistance + angleWeight * (Mathf.Abs(calcAngle));
282 
283  if (minWeightSum > calcWeightSum)
284  {
285  minWeightSum = calcWeightSum;
286  keyframeIndex = i;
287  }
288  }
289  }
290  }
291 }
bool AutoCamera
Change the view point of the scene view. scene viewpoint in editor. Select the keyframe closest to th...
int KeyframeIndex
Change the keyframe number of imported 3D map.
bool Load(string fileName)
Read map file and create keyframe and mappoint as Unity3d object.
Handles 3D map file for authoring. Map controller includes mappoint controller and keyframe controlle...
int MaxKeyframeCount
Get the number of keyframes for the imported map.
void ApplyViewCamera(Vector3 position, Quaternion quaternion)
Select the keyframe closest to the scene view.
bool Transparent
Changes the loaded map to translucent state.
Map created by Visual SLAM renderer
void UpdateMapViewer()
Updated the control changes of the authoring tool in the scene view.
bool ShowMesh
Reconstruct map point cloud to 3D for authoring.