ArViewer  Android Version
Arvos - Augmented reality viewer open source
 All Classes Namespaces Files Functions Variables
PoiObject.java
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013, Peter Graf
3 
4  This file is part of Arvos - AR Viewer Open Source for Android.
5  Arvos is free software.
6 
7  This program is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>.
19 
20  For more information on the AR Viewer Open Source or Peter Graf,
21  please see: http://www.mission-base.com/.
22  */
23 
24 package com.mission_base.arviewer_android.viewer;
25 
26 import android.graphics.*;
27 import com.mission_base.arviewer_android.*;
28 import com.mission_base.arviewer_android.viewer.opengl.*;
29 import java.util.*;
30 import org.json.*;
31 
38 public class PoiObject
39 {
40  private static int mNextId = 0;
41 
42  private static int getNextId()
43  {
44  return ++mNextId;
45  }
46 
47  public int mId;
48  public String mName;
49  public String mTexture;
50  public String mBillboardHandling;
51 
52  public long mStartTime;
53  public long mDuration;
54 
55  public boolean mLoop;
56  public boolean mIsActive;
57 
58  public List<String> mOnClickUrls;
59  public List<String> mOnClickActivates;
60  public List<String> mOnClickDeactivates;
61 
62  public List<String> mOnDurationEndUrls;
63  public List<String> mOnDurationEndActivates;
64  public List<String> mOnDurationEndDeactivates;
65 
66  public float[] mStartPosition;
67  public float[] mEndPosition;
68 
69  public float[] mStartScale;
70  public float[] mEndScale;
71 
72  public float[] mStartRotation;
73  public float[] mEndRotation;
74 
75  public long mTimeStarted;
76  public Poi mParent;
77 
78  public Bitmap mBitmap;
79 
86  public PoiObject(Poi parent)
87  {
88  mId = getNextId();
89  mParent = parent;
91  mIsActive = true;
92  }
93 
102  public void parse(JSONObject jsonPoiObject) throws JSONException
103  {
104  if (jsonPoiObject != null)
105  {
106  mTexture = jsonPoiObject.getString("texture");
107 
108  mName = jsonPoiObject.has("name") ? jsonPoiObject.getString("name") : null;
109  mBillboardHandling = jsonPoiObject.has("billboardHandling") ? jsonPoiObject.getString("billboardHandling") : null;
110  if (mBillboardHandling != null //
114  {
115  throw new JSONException("Illegal value for billboardHandling: " + mBillboardHandling);
116  }
117 
118  mStartTime = jsonPoiObject.has("startTime") ? jsonPoiObject.getInt("startTime") : 0;
119  mDuration = jsonPoiObject.has("duration") ? jsonPoiObject.getInt("duration") : 0;
120  mLoop = jsonPoiObject.has("loop") ? jsonPoiObject.getBoolean("loop") : true;
121  mIsActive = jsonPoiObject.has("isActive") ? jsonPoiObject.getBoolean("isActive") : true;
122 
123  mStartPosition = parseVec3f(jsonPoiObject, "startPosition");
124  if (mStartPosition == null)
125  {
126  mStartPosition = new float[] { 0f, 0f, 0f };
127  }
128  mEndPosition = parseVec3f(jsonPoiObject, "endPosition");
129 
130  mStartScale = parseVec3f(jsonPoiObject, "startScale");
131  mEndScale = parseVec3f(jsonPoiObject, "endScale");
132 
133  mStartRotation = parseVec4f(jsonPoiObject, "startRotation");
134  mEndRotation = parseVec4f(jsonPoiObject, "endRotation");
135 
136  if (jsonPoiObject.has("onClick"))
137  {
138  JSONArray jsonArray = new JSONArray(jsonPoiObject.getString("onClick"));
139  if (jsonArray != null && jsonArray.length() > 0)
140  {
141  for (int i = 0; i < jsonArray.length(); i++)
142  {
143  JSONObject jsonOnClick = jsonArray.getJSONObject(i);
144 
145  if (jsonOnClick.has("url"))
146  {
147  if (mOnClickUrls == null)
148  {
149  mOnClickUrls = new LinkedList<String>();
150  }
151  mOnClickUrls.add(jsonOnClick.getString("url"));
152  }
153  if (jsonOnClick.has("activate"))
154  {
155  if (mOnClickActivates == null)
156  {
157  mOnClickActivates = new LinkedList<String>();
158  }
159  mOnClickActivates.add(jsonOnClick.getString("activate"));
160  }
161  if (jsonOnClick.has("deactivate"))
162  {
163  if (mOnClickDeactivates == null)
164  {
165  mOnClickDeactivates = new LinkedList<String>();
166  }
167  mOnClickDeactivates.add(jsonOnClick.getString("deactivate"));
168  }
169  }
170  }
171  }
172  if (jsonPoiObject.has("onDurationEnd"))
173  {
174  JSONArray jsonArray = new JSONArray(jsonPoiObject.getString("onDurationEnd"));
175  if (jsonArray != null && jsonArray.length() > 0)
176  {
177  for (int i = 0; i < jsonArray.length(); i++)
178  {
179  JSONObject jsonOnDurationEnd = jsonArray.getJSONObject(i);
180  if (jsonOnDurationEnd.has("url"))
181  {
182  if (mOnDurationEndUrls == null)
183  {
184  mOnDurationEndUrls = new LinkedList<String>();
185  }
186  mOnDurationEndUrls.add(jsonOnDurationEnd.getString("url"));
187  }
188  if (jsonOnDurationEnd.has("activate"))
189  {
190  if (mOnDurationEndActivates == null)
191  {
192  mOnDurationEndActivates = new LinkedList<String>();
193  }
194  mOnDurationEndActivates.add(jsonOnDurationEnd.getString("activate"));
195  }
196  if (jsonOnDurationEnd.has("deactivate"))
197  {
198  if (mOnDurationEndDeactivates == null)
199  {
200  mOnDurationEndDeactivates = new LinkedList<String>();
201  }
202  mOnDurationEndDeactivates.add(jsonOnDurationEnd.getString("deactivate"));
203  }
204  }
205  }
206  }
207  }
208  }
209 
218  public static float[] parseVec3f(JSONObject jsonObject, String name) throws JSONException
219  {
220  float[] result = null;
221  if (jsonObject.has(name))
222  {
223  result = new float[3];
224 
225  JSONArray jsonArray = new JSONArray(jsonObject.getString(name));
226  if (jsonArray != null && jsonArray.length() > 0)
227  {
228  JSONObject jsonVec3f = jsonArray.getJSONObject(0);
229  result[0] = jsonVec3f.has("x") ? (float) jsonVec3f.getDouble("x") : 0f;
230  result[1] = jsonVec3f.has("y") ? (float) jsonVec3f.getDouble("y") : 0f;
231  result[2] = jsonVec3f.has("z") ? (float) jsonVec3f.getDouble("z") : 0f;
232  }
233  }
234  return result;
235  }
236 
245  public static float[] parseVec4f(JSONObject jsonObject, String name) throws JSONException
246  {
247  float[] result = null;
248  if (jsonObject.has(name))
249  {
250  result = new float[4];
251 
252  JSONArray jsonArray = new JSONArray(jsonObject.getString(name));
253  if (jsonArray != null && jsonArray.length() > 0)
254  {
255  JSONObject jsonVec4f = jsonArray.getJSONObject(0);
256  result[0] = jsonVec4f.has("x") ? (float) jsonVec4f.getDouble("x") : 0f;
257  result[1] = jsonVec4f.has("y") ? (float) jsonVec4f.getDouble("y") : 0f;
258  result[2] = jsonVec4f.has("z") ? (float) jsonVec4f.getDouble("z") : 0f;
259  result[3] = jsonVec4f.has("a") ? (float) jsonVec4f.getDouble("a") : 0f;
260  }
261  }
262  return result;
263  }
264 
265  private ArvosObject findArvosObject(List<ArvosObject> arvosObjects)
266  {
267  for (ArvosObject arvosObject : arvosObjects)
268  {
269  if (arvosObject.mId == mId)
270  {
271  return arvosObject;
272  }
273  }
274  return new ArvosObject(mId);
275  }
276 
277  private long mWorldStartTime = -1;
278  private long mWorldIteration = -1;
279 
289  public ArvosObject getObject(long time, List<ArvosObject> arvosObjects)
290  {
291  if (mWorldStartTime < 0)
292  {
293  mWorldStartTime = time;
294  mWorldIteration = 0;
295  }
296 
297  if (!mIsActive)
298  {
299  return null;
300  }
301 
302  ArvosObject result = null;
303 
304  long duration = (mDuration > 0) ? mDuration : mParent.mAnimationDuration;
305  if (mParent.mAnimationDuration <= 0 || duration <= 0)
306  {
307  // No animation, use start values
308  //
309  result = findArvosObject(arvosObjects);
310  result.mName = mName;
311  result.mTexture = mTexture;
313  if (result.mPosition == null)
314  {
315  result.mPosition = new float[3];
316  }
317  result.mPosition[0] = mStartPosition[0];
318  result.mPosition[1] = mStartPosition[1];
319  result.mPosition[2] = mStartPosition[2];
320  result.mScale = mStartScale;
321  result.mRotation = mStartRotation;
322  result.mBitmap = mBitmap;
323 
324  return result;
325  }
326 
327  long worldTime = time - mWorldStartTime;
328  long iteration = worldTime / mParent.mAnimationDuration;
329  if (iteration > mWorldIteration)
330  {
331  mWorldIteration = iteration;
332  mParent.requestStop(this);
333  return null;
334  }
335 
336  if (mTexture == null)
337  {
338  return null;
339  }
340 
341  long loopTime = worldTime % mParent.mAnimationDuration;
342  if (loopTime < mStartTime || loopTime >= mStartTime + duration)
343  {
344  return null;
345  }
346 
347  float factor = loopTime - mStartTime;
348  factor /= duration;
349 
350  result = findArvosObject(arvosObjects);
351  result.mName = mName;
352  result.mTexture = mTexture;
354  result.mPosition = mStartPosition;
355  result.mScale = mStartScale;
356  result.mRotation = mStartRotation;
357  result.mBitmap = mBitmap;
358 
359  if (mStartPosition != null && mEndPosition != null && factor > 0)
360  {
361  result.mPosition = new float[3];
362  result.mPosition[0] = mStartPosition[0] + factor * (mEndPosition[0] - mStartPosition[0]);
363  result.mPosition[1] = mStartPosition[1] + factor * (mEndPosition[1] - mStartPosition[1]);
364  result.mPosition[2] = mStartPosition[2] + factor * (mEndPosition[2] - mStartPosition[2]);
365  }
366 
367  if (mStartScale != null && mEndScale != null && factor > 0)
368  {
369  result.mScale = new float[3];
370  result.mScale[0] = mStartScale[0] + factor * (mEndScale[0] - mStartScale[0]);
371  result.mScale[1] = mStartScale[1] + factor * (mEndScale[1] - mStartScale[1]);
372  result.mScale[2] = mStartScale[2] + factor * (mEndScale[2] - mStartScale[2]);
373  }
374 
375  if (mStartRotation != null && mEndRotation != null && factor > 0)
376  {
377  result.mRotation = new float[4];
378  result.mRotation[0] = mStartRotation[0] + factor * (mEndRotation[0] - mStartRotation[0]);
379  result.mRotation[1] = mStartRotation[1] + factor * (mEndRotation[1] - mStartRotation[1]);
380  result.mRotation[2] = mStartRotation[2] + factor * (mEndRotation[2] - mStartRotation[2]);
381  result.mRotation[3] = mStartRotation[3] + factor * (mEndRotation[3] - mStartRotation[3]);
382  }
383  return result;
384  }
385 
389  public void stop()
390  {
391  onDurationEnd();
392 
393  if (mLoop)
394  {
395  mParent.requestStart(this);
396  }
397  else
398  {
399  mIsActive = false;
400  }
401  }
402 
409  public void start(long time)
410  {
411  mTimeStarted = time;
412  }
413 
417  public void onClick()
418  {
420  }
421 
422  private void onDurationEnd()
423  {
425  }
426 
427  private void handleAction(List<String> activates, List<String> deactivates, List<String> urls)
428  {
429  if (activates != null)
430  {
431  for (String otherObjectName : activates)
432  {
433  PoiObject poiObject = mParent.findPoiObject(otherObjectName);
434  if (poiObject != null)
435  {
436  poiObject.mIsActive = true;
437  mParent.requestActivate(poiObject);
438  }
439  }
440  }
441  if (deactivates != null)
442  {
443  for (String otherObjectName : deactivates)
444  {
445  PoiObject poiObject = mParent.findPoiObject(otherObjectName);
446  if (poiObject != null)
447  {
448  poiObject.mIsActive = false;
449  mParent.requestDeactivate(poiObject);
450  }
451  }
452  }
453  if (urls != null)
454  {
455  for (String url : urls)
456  {
457  Arvos.getInstance().startWebViewer(url);
458  }
459  }
460  }
461 }