我将从试图解释本示例中发生的事情开始。从UI.cs中的调用开始到Query_OnFloor_AwayFromMe()...
- 这会调用LevelSolver.cs。在此方法是创建一个新的PlacementQuery对象并调用PlaceObjectAsync。
- PlaceObjectAsync创建了以System.Threading.Tasks.Task.Run通话主叫地方空间理解的实际工作是越来越做了一个新的线程。这项工作必须在一个单独的线程,因为它需要很长的时间,所以它需要跨越多个帧将被执行的程序将会执行期间锁定来完成。
- 在新线程PlaceObject被调用时,这将实际调用空间理解(SpatialUnderstandingDllObjectPlacement.Solver_PlaceObject),这是对C++ HoloToolkit的调用,这是需要很长时间的调用。完成后,结果将添加到基本上是工作队列的placementResults中。
- 在LevelSolver.cs有一个更新的方法,这将调用每一个团结绘制一个新的帧的时间。在这里调用Draw_PlacementResults。
- Draw_PlacementResults循环遍历placementResults工作队列中的每个结果,并调用LineDrawer.cs中的Draw_AnimatedBox
- 这就是您如何访问我们在上一个问题中讨论的Draw_Box的调用。
所以,另一个问题是如何修改这个例子来把你自己的模型放在适当的位置。我建议在LevelSolver.cs中进行修改。尝试改变更新(),以这样的:
private void Update()
{
// Can't do any of this till we're done with the scanning phase
if (SpatialUnderstanding.Instance.ScanState != SpatialUnderstanding.ScanStates.Done)
{
return;
}
// Make sure the solver has been initialized
if (!IsSolverInitialized &&
SpatialUnderstanding.Instance.AllowSpatialUnderstanding)
{
InitializeSolver();
}
// Constraint queries
if (SpatialUnderstanding.Instance.ScanState == SpatialUnderstanding.ScanStates.Done)
{
Update_Queries();
}
// Handle async query results
ProcessPlacementResults();
MyProcessPlacementResults();
}
这将导致其停止绘画工具盒,而是称之为“MyProcessPlacementResults”处理做的结果的东西。我会向LevelSolver.cs添加一个像这样的方法。 (在代码中,我借用我创建一个树)
private void MyProcessPlacementResults()
{
if (placementResults.Count > 0)
{
var toPlace = placementResults.Dequeue();
var rotation = Quaternion.LookRotation(toPlace.Result.Forward, Vector3.up);
CreateTree(toPlace.Result.Position, rotation);
}
}
下面是我用实际实例树中的正确位置代码:
private GameObject ThisIsYourCustomModelInMineItWasATree;
private Vector3 TheSizeIPassedToSpatialUnderstanding = new Vector3(1, 1, 1);
public void CreateHologram(Vector3 positionCenter, Quaternion rotation)
{
ThisIsYourCustomModelInMineItWasATree = GameObject.CreatePrimitive(PrimitiveType.Sphere);
GameObject newObject = Instantiate(ThisIsYourCustomModelInMineItWasATree, positionCenter, rotation) as GameObject;
if (newObject != null)
{
// Set the parent of the new object the GameObject it was placed on
newObject.transform.parent = gameObject.transform;
newObject.transform.localScale = StretchToFit(ThisIsYourCustomModelInMineItWasATree, TheSizeIPassedToSpatialUnderstanding);
newObject.AddComponent<MeshCollider>();
}
}
和公正的这里完整性是我习惯了缩放到所需大小的代码:
private Vector3 StretchToFit(GameObject obj, Vector3 desiredSize)
{
var curBounds = GetBoundsForAllChildren(obj).size;
return new Vector3(desiredSize.x/curBounds.x/2, desiredSize.y, desiredSize.z/curBounds.z/2);
}
private Bounds GetBoundsForAllChildren(GameObject findMyBounds)
{
Bounds result = new Bounds(Vector3.zero, Vector3.zero);
foreach (var renderer in findMyBounds.GetComponentsInChildren<Renderer>())
{
if (result.extents == Vector3.zero)
{
result = renderer.bounds;
}
else
{
result.Encapsulate(renderer.bounds);
}
}
return result;
}
我也改变了私有变量placementResults从列表添加到队列。我这样做是因为列表被用来在每一帧中绘制一个框。我们希望有一个队列,因为我们要一次实例化一个新的对象,并让Unity引擎管理。找到这行:
private List<PlacementResult> placementResults = new List<PlacementResult>();
并将其更改为:
private Queue<PlacementResult> placementResults = new Queue<PlacementResult>();
做出这样的转变,你将需要解决几个地方之后。删除方法Draw_PlacementResults,它不再被使用。更改调用placementResults.Add的两个位置到placementResults.Enqueue。
根据您以前的问题(http://stackoverflow.com/questions/40728179/hololens-placing-objects-with-spatial-understanding/40729295#40729295),您已成功替换为您的全息图的默认框自己的,但你正在努力得到它的正确和规模的地方,大小合适,之前我张贴的答案,是正确的? –
我想我没有,但它是一个游戏物体我忘了关。所以我再次回到那里:( – firativerson
如果你可以发布的地方你目前的代码,我要看看它。 –