Map manager의 visual slam으로 3Dmap을 제작 후 원하는 AR Object를 넣어서 다시 3Dmap으로 저장하고싶습니다.
Please provide your development details as below;
1. SDK Version: 4.0
2. Development Environment: (Native Android)
3. Tracker/Scanner:Tracker
4. License Type(Free)
안녕하세요,. 프로젝트 진행 중 궁금한게 있어서 문의 드립니다.
Map manager의 visual slam으로 3Dmap을 제작 후
Unity에서 원하는 위치에 AR Object를 넣은 뒤에 다시 3Dmap으로 저장하고싶습니다.
즉, 그림과 같이 앱에서 컵, 화분, 캔을 증강시키는 것 같이 유니티에서 원하는 AR Object를 삽입 후 3Dmap파일로 저장하고싶습니다.
3Dmap파일은 Object tracker에서 사용 될 것 입니다.
해당 앱은 컨텐츠 배치부터 결과물에 대한 Object Tracking까지 앱 내에서 수행하기 위한 목적으로 만들어졌습니다.
3dmap 파일 획득 + 사용자 제작 Object를 배치하시려면
Android/data/com.maxst.arsdk.demoapp 의 경로에서 3dmap 파일을 획득하실 수 있습니다.
그 후 획득한 3dmap을 Object Tracker에서 로드하여 원하는 컨텐츠를 배치하시면 됩니다.
다만, 위 Map Manager에서 생성된 3dmap은 SDK 4.0 이하의 버전과 호환된다는점 유의하시기 바랍니다.
감사합니다.
Leo
Maxst Support Team
답변 감사합니다. 질문 의도와 조금 다른것 같은데요.
데모앱상에서 AR Object를 배치하는 것이 아니라. unity에서 AR object가 없는 상태에서 AR object를 삽입 후 3Dmap파일로 저장하고 싶습니다.
unity에서 AR object를 삽입 후 3Dmap파일로 저장하는 방법을 물어보고 싶습니다.
3Dmap파일은 현재 보이는 3D 공간을 맵으로 생성하는 것입니다.
컨텐츠는 현실세계에 존재하는 것이 아니므로 3Dmap 파일에 같이 저장되지 않습니다.
카메라로 보이는 화면 자체를 3Dmap으로 생성하기 때문입니다.
원하는 컨텐츠를 따로 저장하고 배치하시는 방법은 컨텐츠의 좌표를 json과 같은 파일로 따로 저장 후
맵 파일이 인식될 때 해당 맵에 저장된 컨텐츠를 같이 로드하는 방법으로 구현하시면 됩니다.
감사합니다.
Leo
Maxst Support Team
답변 감사합니다. 이에 따른 2가지 질문사항이 있습니다.
1. 아래와 같이 object tracker에서 3dmapfile을 추가하는데 addTrackerData를 호출하는 것과 같이
컨텐츠를 따로 저장하고 컨텐츠의 좌표가 저장된 JSON같은 파일을 동일한 방법으로 추가하면 되나요?
@Override protected void onCreate(Bundle savedInstanceState) { ... TrackerManager.getInstance().addTrackerData(mapFileName, false); TrackerManager.getInstance().loadTrackerData(); }
2. 위의 답변에서 말씀하신 json과 같은 파일에서 format을 알 수 있을 까요? 어떤 파라미터와 데이터가 필요한지...
감사합니다.
저희가 제공하는 SDK에서는 컨텐츠에 전혀 관여를 하지 않습니다.
저희 SDK에는 컨텐츠에 관련된 데이터를 받거나 저장하거나 로드하는 함수가 전혀 없습니다.
저장하려는 컨텐츠에 대해 json 데이터를 저장하는 형식(파라미터, 데이터), 저장하는 위치 등
어떤 정보들을 저장하고 어떤 경로에 저장할지는 개발자가 직접 정의해 주어야할 부분입니다.
또한, 컨텐츠를 json 데이터로 저장하는 방법이 있다는 예시를 준 것일 뿐이며,
txt 파일 혹은 원하시는 형식으로 파일입출력을 하여 원하시는대로 자유롭게 사용하시면 됩니다.
이번 마케팅 앱에 구현된 부분을 간단히 발췌해서 보여드리겠습니다.
아래는 ObjectTracker 스크립트에 구현된 일부입니다.
선행단계로 맵을 학습 및 생성하는 부분에서 파일명.3dmap 파일이 저장된 경로와 같은 경로에
파일명.data 라는 이름으로 미리 저장하였습니다.
또한, 맵을 학습 및 저장까지 Visual SLAM 기능을 구현하는 과정까지 SDK 내부 코드를 건드린것은 전혀 없으며
SDK에서 제공하는 함수들만 사용하여 학습 및 생성까지 할 수 있는 앱을 만들었다는점 미리 알려드립니다.
[SerializeField]
private ModelBehaviour prefab_Youtube;
public Dictionary<string, List<ModelBehaviour>> MapList = new Dictionary<string, List<ModelBehaviour>>();
void Start()
{
int mapCount = 0;
foreach (string trackerDataPath in SceneTempSaveManager.GetInstance().objectTrackerFiles)
{
AddTrackerData(trackerDataPath);
string filenamewithoutExtension = Path.GetFileNameWithoutExtension(trackerDataPath);
//Debug.Log("filenamewithoutExtension Substring = " + filenamewithoutExtension);
MapList.Add(filenamewithoutExtension, loadContentPositionToList(trackerDataPath));
mapCount++;
}
}
private List loadContentPositionToList(string mapfilePath)
{
List<ModelBehaviour> ModelList = new List<ModelBehaviour>();
string positionPath = Path.ChangeExtension(mapfilePath, "data");
string loadJson = readStringFromFile(positionPath);
Debug.Log("#########loadJSON = " + loadJson);
var loadData = JsonUtility.FromJson(loadJson);
foreach (Content element in loadData.contents)
{
ModelBehaviour newModel = new ModelBehaviour();
if (element.contentType == 0)
{
newModel = Instantiate(prefab_Youtube, Vector3.zero, Quaternion.Euler(0, 0, 0)) as ModelBehaviour;
}
newModel.movePosition.x = element.movePosition.x;
newModel.movePosition.y = element.movePosition.y;
newModel.movePosition.z = element.movePosition.z;
ModelList.Add(newModel);
}
return ModelList;
}
위 코드에서 AddTrackerData 함수를 통해 3dmap의 경로를 SDK에 전달만 해 줄 뿐,
파일에서 JSON 형태를 읽어오는 부분은 별도의 함수에서 파일입출력을 통해 하였습니다.
trackerDataPath는 전체경로/맵파일명.3dmap 이라는 string이기 때문에
맵 파일명만 잘라내어 <맵파일명, 컨텐츠리스트> 라는 두개의 키와 값으로 저장하여
추후 Update() 함수에서 저장된 맵파일명을 통해
TrackingState trackingState = TrackerManager.GetInstance().UpdateTrackingState();
TrackingResult trackingResult = trackingState.GetTrackingResult();
Trackable trackable = trackingResult.GetTrackable(0);
foreach (KeyValuePair> pair in MapList)
{
if(pair.Key == trackable.GetName())
{
foreach (ModelBehaviour element in pair.Value)
{
element.gameObject.SetActive(true);
Matrix4x4 poseMatrix = trackable.GetPose() * Matrix4x4.Translate(element.movePosition);
element.transform.position = MatrixUtils.PositionFromMatrix(poseMatrix);
element.transform.rotation = MatrixUtils.QuaternionFromMatrix(poseMatrix);
}
}
}
트래킹 결과로부터 얻어온 3dmap 파일명과 저장된 키값을 비교하여 사용하였습니다.
코드 찬찬히 살펴보시고, 도움이 되셨으면 좋겠습니다.
감사합니다.
Leo
Maxst Support Team