- // Copyright (c) Microsoft Corporation. All rights reserved.
- // Licensed under the MIT License. See LICENSE in the project root for license information.
-
- using UnityEngine;
- using System.Collections;
- using System.Runtime.InteropServices;
- using System;
- using System.Collections.Generic;
-
- namespace HoloToolkit.Unity
- {
- /// <summary>
- /// Encapsulates the object placement queries of the understanding DLL.
- /// These queries will not be valid until after scanning is finalized.
- /// </summary>
- public static class SpatialUnderstandingDllObjectPlacement
- {
- /// <summary>
- /// Defines an object placement query. A query consists of
- /// a type a name, type, set of rules, and set of constraints.
- ///
- /// Rules may not be violated by the returned query. Possible
- /// locations that satisfy the type and rules are selected
- /// by optimizing within the constraint list.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct ObjectPlacementDefinition
- {
- /// <summary>
- /// Type of object placement. Each type has a custom set
- /// of parameter.
- /// </summary>
- public enum PlacementType
- {
- Place_OnFloor,
- Place_OnWall,
- Place_OnCeiling,
- Place_OnShape,
- Place_OnEdge,
- Place_OnFloorAndCeiling,
- Place_RandomInAir,
- Place_InMidAir,
- Place_UnderPlatformEdge,
- };
-
- /// <summary>
- /// Type of wall.
- /// External walls bound the playspace. Virtual walls are created
- /// at the edge of the playspace when an external wall does not
- /// exist.
- /// </summary>
- [FlagsAttribute]
- public enum WallTypeFlags
- {
- None = 0,
- Normal = (1 << 0),
- External = (1 << 1),
- Virtual = (1 << 2),
- ExternalVirtual = (1 << 3),
- };
-
- /// <summary>
- /// Constructs an object placement query definition requiring the object to
- /// be placed on the floor.
- /// </summary>
- /// <param name="halfDims">Required half size of the requested bounding volume</param>
- /// <returns>Constructed object placement definition</returns>
- public static ObjectPlacementDefinition Create_OnFloor(Vector3 halfDims)
- {
- ObjectPlacementDefinition placement = new ObjectPlacementDefinition();
- placement.Type = PlacementType.Place_OnFloor;
- placement.HalfDims = halfDims;
- return placement;
- }
-
- /// <summary>
- /// Constructs an object placement query definition requiring the object to
- /// be placed on a wall.
- /// </summary>
- /// <param name="halfDims">Required half size of the requested bounding volume</param>
- /// <param name="heightMin">Minimum height of the requested volume above the floor</param>
- /// <param name="heightMax">Maximum height of the requested volume above the floor</param>
- /// <param name="wallTypes">Bit mask of possible walls to consider, defined by WallTypeFlags</param>
- /// <param name="marginLeft">Required empty wall space to the left of the volume, as defined by facing the wall</param>
- /// <param name="marginRight">Required empty wall space to the right of the volume, as defined by facing the wall</param>
- /// <returns>Constructed object placement definition</returns>
- public static ObjectPlacementDefinition Create_OnWall(
- Vector3 halfDims,
- float heightMin,
- float heightMax,
- WallTypeFlags wallTypes = WallTypeFlags.External | WallTypeFlags.Normal,
- float marginLeft = 0.0f,
- float marginRight = 0.0f)
- {
- ObjectPlacementDefinition placement = new ObjectPlacementDefinition();
- placement.Type = PlacementType.Place_OnWall;
- placement.HalfDims = halfDims;
- placement.PlacementParam_Float_0 = heightMin;
- placement.PlacementParam_Float_1 = heightMax;
- placement.PlacementParam_Float_2 = marginLeft;
- placement.PlacementParam_Float_3 = marginRight;
- placement.WallFlags = (int)wallTypes;
- return placement;
- }
-
- /// <summary>
- /// Constructs an object placement query definition requiring the object to
- /// be place on the ceiling.
- /// </summary>
- /// <param name="halfDims">Required half size of the requested bounding volume</param>
- /// <returns>Constructed object placement definition</returns>
- public static ObjectPlacementDefinition Create_OnCeiling(Vector3 halfDims)
- {
- ObjectPlacementDefinition placement = new ObjectPlacementDefinition();
- placement.Type = PlacementType.Place_OnCeiling;
- placement.HalfDims = halfDims;
- return placement;
- }
-
- /// <summary>
- /// Constructs an object placement query definition requiring the object to
- /// be placed on top of another object placed object.
- /// </summary>
- /// <param name="halfDims">Required half size of the requested bounding volume</param>
- /// <param name="shapeName">Name of the placed object</param>
- /// <param name="componentIndex">Index of the component within shapeName</param>
- /// <returns>Constructed object placement definition</returns>
- public static ObjectPlacementDefinition Create_OnShape(Vector3 halfDims, string shapeName, int componentIndex)
- {
- ObjectPlacementDefinition placement = new ObjectPlacementDefinition();
- placement.Type = PlacementType.Place_OnShape;
- placement.HalfDims = halfDims;
- placement.PlacementParam_Str_0 = SpatialUnderstanding.Instance.UnderstandingDLL.PinString(shapeName);
- placement.PlacementParam_Int_0 = componentIndex;
- return placement;
- }
-
- /// <summary>
- /// Constructs an object placement query definition requiring the object to
- /// be placed on the edge of a platform.
- /// </summary>
- /// <param name="halfDims">Required half size of the requested bounding volume</param>
- /// <param name="halfDimsBottom">Half size of the bottom part of the placement volume</param>
- /// <returns>Constructed object placement definition</returns>
- public static ObjectPlacementDefinition Create_OnEdge(Vector3 halfDims, Vector3 halfDimsBottom)
- {
- ObjectPlacementDefinition placement = new ObjectPlacementDefinition();
- placement.Type = PlacementType.Place_OnEdge;
- placement.HalfDims = halfDims;
- placement.PlacementParam_Float_0 = halfDimsBottom.x;
- placement.PlacementParam_Float_1 = halfDimsBottom.y;
- placement.PlacementParam_Float_2 = halfDimsBottom.z;
- return placement;
- }
-
- /// <summary>
- /// Constructs an object placement query definition requiring the object to
- /// be have space on the floor and ceiling within the same vertical space.
- /// </summary>
- /// <param name="halfDims">Required half size of the requested bounding volume</param>
- /// <param name="halfDimsBottom">Half size of the bottom part of the placement volume</param>
- /// <returns>Constructed object placement definition</returns>
- public static ObjectPlacementDefinition Create_OnFloorAndCeiling(Vector3 halfDims, Vector3 halfDimsBottom)
- {
- ObjectPlacementDefinition placement = new ObjectPlacementDefinition();
- placement.Type = PlacementType.Place_OnFloorAndCeiling;
- placement.HalfDims = halfDims;
- placement.PlacementParam_Float_0 = halfDimsBottom.x;
- placement.PlacementParam_Float_1 = halfDimsBottom.y;
- placement.PlacementParam_Float_2 = halfDimsBottom.z;
- return placement;
- }
-
- /// <summary>
- /// Constructs an object placement query definition requiring the object to
- /// be placed floating in space, within the playspace. Spaces visible from the
- /// center of the playspace are favored.
- /// </summary>
- /// <param name="halfDims">Required half size of the requested bounding volume</param>
- /// <returns>Constructed object placement definition</returns>
- public static ObjectPlacementDefinition Create_RandomInAir(Vector3 halfDims)
- {
- ObjectPlacementDefinition placement = new ObjectPlacementDefinition();
- placement.Type = PlacementType.Place_RandomInAir;
- placement.HalfDims = halfDims;
- return placement;
- }
-
- /// <summary>
- /// Constructs an object placement query definition requiring the object to
- /// be placed floating in space, within the playspace. This query requires that
- /// other objects do not collide with the placement volume.
- /// </summary>
- /// <param name="halfDims">Required half size of the requested bounding volume</param>
- /// <returns>Constructed object placement definition</returns>
- public static ObjectPlacementDefinition Create_InMidAir(Vector3 halfDims)
- {
- ObjectPlacementDefinition placement = new ObjectPlacementDefinition();
- placement.Type = PlacementType.Place_InMidAir;
- placement.HalfDims = halfDims;
- return placement;
- }
-
- /// <summary>
- /// Constructs an object placement query definition requiring the object to
- /// be place under a platform edge.
- /// </summary>
- /// <param name="halfDims">Required half size of the requested bounding volume</param>
- /// <returns>Constructed object placement definition</returns>
- public static ObjectPlacementDefinition Create_UnderPlatformEdge(Vector3 halfDims)
- {
- ObjectPlacementDefinition placement = new ObjectPlacementDefinition();
- placement.Type = PlacementType.Place_UnderPlatformEdge;
- placement.HalfDims = halfDims;
- return placement;
- }
-
- public PlacementType Type;
- public int PlacementParam_Int_0;
- public float PlacementParam_Float_0;
- public float PlacementParam_Float_1;
- public float PlacementParam_Float_2;
- public float PlacementParam_Float_3;
- public IntPtr PlacementParam_Str_0;
- public int WallFlags;
- public Vector3 HalfDims;
- };
-
- /// <summary>
- /// Defines an object placement rule. Rules are one part of an object
- /// placement definition. Rules may not be violated by the returned query.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct ObjectPlacementRule
- {
- /// <summary>
- /// Type of object placement rule. Each rule is defined by its
- /// type and a set of per-type parameters. The supplied static
- /// construction functions may be used to create rules.
- /// </summary>
- public enum ObjectPlacementRuleType
- {
- Rule_AwayFromPosition,
- Rule_AwayFromWalls,
- Rule_AwayFromOtherObjects,
- };
-
- /// <summary>
- /// Constructs an object placement rule requiring the placement volume to
- /// be placed a minimum distance away from the specified position.
- /// </summary>
- /// <param name="position">Defines the center position for the center of the invalid placement space.</param>
- /// <param name="minDistance">Defines the radius of the invalid placement space.</param>
- /// <returns>Constructed object placement rule</returns>
- public static ObjectPlacementRule Create_AwayFromPosition(Vector3 position, float minDistance)
- {
- ObjectPlacementRule rule = new ObjectPlacementRule();
- rule.Type = ObjectPlacementRuleType.Rule_AwayFromPosition;
- rule.RuleParam_Vec3_0 = position;
- rule.RuleParam_Float_0 = minDistance;
- return rule;
- }
-
- /// <summary>
- /// Constructs an object placement rule requiring the placement volume to
- /// be placed a minimum distance away from any wall
- /// </summary>
- /// <param name="minDistance">Minimum distance from a wall</param>
- /// <param name="minWallHeight">Minimum height of a wall to be considered by this rule</param>
- /// <returns>Constructed object placement rule</returns>
- public static ObjectPlacementRule Create_AwayFromWalls(float minDistance, float minWallHeight = 0.0f)
- {
- ObjectPlacementRule rule = new ObjectPlacementRule();
- rule.Type = ObjectPlacementRuleType.Rule_AwayFromWalls;
- rule.RuleParam_Float_0 = minDistance;
- rule.RuleParam_Float_1 = minWallHeight;
- return rule;
- }
-
- /// <summary>
- /// Constructs an object placement rule requiring the placement volume to
- /// be placed a minimum distance away from other placed objects
- /// </summary>
- /// <param name="minDistance">Minimum distance from other placed objects</param>
- /// <returns>Constructed object placement rule</returns>
- public static ObjectPlacementRule Create_AwayFromOtherObjects(float minDistance)
- {
- ObjectPlacementRule rule = new ObjectPlacementRule();
- rule.Type = ObjectPlacementRuleType.Rule_AwayFromOtherObjects;
- rule.RuleParam_Float_0 = minDistance;
- return rule;
- }
-
- public ObjectPlacementRuleType Type;
- public int RuleParam_Int_0;
- public float RuleParam_Float_0;
- public float RuleParam_Float_1;
- public Vector3 RuleParam_Vec3_0;
- };
-
- /// <summary>
- /// Defines an object placement constraint. Constraints are one part of an object
- /// placement definition. Possible object placement locations are picked by the
- /// location that minimally violates the set of constraints.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct ObjectPlacementConstraint
- {
- /// <summary>
- /// Types of object placement constraints
- /// </summary>
- public enum ObjectPlacementConstraintType
- {
- Constraint_NearPoint,
- Constraint_NearWall,
- Constraint_AwayFromWalls,
- Constraint_NearCenter,
- Constraint_AwayFromOtherObjects,
- Constraint_AwayFromPoint
- };
-
- /// <summary>
- /// Constructs an object placement constraint requesting that the placement volume
- /// be placed no closer than minDistance and no further than maxDistance from
- /// the specified position.
- /// </summary>
- /// <param name="position">The center point from switch minDistance and maxDistance define their volumes</param>
- /// <param name="minDistance">The minimum distance from position to place the object</param>
- /// <param name="maxDistance">The maximum distance from position to place the object</param>
- /// <returns>Constructed object placement constraint</returns>
- public static ObjectPlacementConstraint Create_NearPoint(Vector3 position, float minDistance = 0.0f, float maxDistance = 0.0f)
- {
- ObjectPlacementConstraint constraint = new ObjectPlacementConstraint();
- constraint.Type = ObjectPlacementConstraintType.Constraint_NearPoint;
- constraint.RuleParam_Vec3_0 = position;
- constraint.RuleParam_Float_0 = minDistance;
- constraint.RuleParam_Float_1 = maxDistance;
- return constraint;
- }
-
- /// <summary>
- /// Constructs an object placement constraint requesting that the placement volume
- /// be placed no closer than minDistance and no further than maxDistance from
- /// a wall.
- /// </summary>
- /// <param name="minDistance">The minimum distance from position to place the object</param>
- /// <param name="maxDistance">The maximum distance from position to place the object</param>
- /// <param name="minWallHeight">Minimum height of a wall to be considered by this rule</param>
- /// <param name="includeVirtualWalls">Indicates virtual walls should be considered in this query</param>
- /// <returns>Constructed object placement constraint</returns>
- public static ObjectPlacementConstraint Create_NearWall(float minDistance = 0.0f, float maxDistance = 0.0f, float minWallHeight = 0.0f, bool includeVirtualWalls = false)
- {
- ObjectPlacementConstraint constraint = new ObjectPlacementConstraint();
- constraint.Type = ObjectPlacementConstraintType.Constraint_NearWall;
- constraint.RuleParam_Float_0 = minDistance;
- constraint.RuleParam_Float_1 = maxDistance;
- constraint.RuleParam_Float_2 = minWallHeight;
- constraint.RuleParam_Int_0 = includeVirtualWalls ? 1 : 0;
- return constraint;
- }
-
- /// <summary>
- /// Constructs an object placement constraint requesting that the placement volume
- /// be placed away from all walls.
- /// </summary>
- /// <returns>Constructed object placement constraint</returns>
- public static ObjectPlacementConstraint Create_AwayFromWalls()
- {
- ObjectPlacementConstraint constraint = new ObjectPlacementConstraint();
- constraint.Type = ObjectPlacementConstraintType.Constraint_AwayFromWalls;
- return constraint;
- }
-
- /// <summary>
- /// Constructs an object placement constraint requesting that the placement volume
- /// be placed near the center of the playspace.
- /// </summary>
- /// <param name="minDistance">The minimum distance from the center to place the object</param>
- /// <param name="maxDistance">The maximum distance from the center to place the object</param>
- /// <returns>Constructed object placement constraint</returns>
- public static ObjectPlacementConstraint Create_NearCenter(float minDistance = 0.0f, float maxDistance = 0.0f)
- {
- ObjectPlacementConstraint constraint = new ObjectPlacementConstraint();
- constraint.Type = ObjectPlacementConstraintType.Constraint_NearCenter;
- constraint.RuleParam_Float_0 = minDistance;
- constraint.RuleParam_Float_1 = maxDistance;
- return constraint;
- }
-
- /// <summary>
- /// Constructs an object placement constraint requesting that the placement volume
- /// be placed away from other place objects.
- /// </summary>
- /// <returns>Constructed object placement constraint</returns>
- public static ObjectPlacementConstraint Create_AwayFromOtherObjects()
- {
- ObjectPlacementConstraint constraint = new ObjectPlacementConstraint();
- constraint.Type = ObjectPlacementConstraintType.Constraint_AwayFromOtherObjects;
- return constraint;
- }
-
- /// <summary>
- /// Constructs an object placement constraint requesting that the placement volume
- /// be placed away from the specified position.
- /// </summary>
- /// <param name="position">The center point from switch minDistance and maxDistance define their volumes</param>
- /// <returns>Constructed object placement constraint</returns>
- public static ObjectPlacementConstraint Create_AwayFromPoint(Vector3 position)
- {
- ObjectPlacementConstraint constraint = new ObjectPlacementConstraint();
- constraint.Type = ObjectPlacementConstraintType.Constraint_AwayFromPoint;
- constraint.RuleParam_Vec3_0 = position;
- return constraint;
- }
-
- public ObjectPlacementConstraintType Type;
- public int RuleParam_Int_0;
- public float RuleParam_Float_0;
- public float RuleParam_Float_1;
- public float RuleParam_Float_2;
- public Vector3 RuleParam_Vec3_0;
- };
-
- /// <summary>
- /// Object placement result. Defines an oriented bounding box result for the
- /// object placement query.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public class ObjectPlacementResult : ICloneable
- {
- public object Clone()
- {
- return this.MemberwiseClone();
- }
-
- public Vector3 Position;
- public Vector3 HalfDims;
- public Vector3 Forward;
- public Vector3 Right;
- public Vector3 Up;
- };
-
- // Functions
- /// <summary>
- /// Initialized the object placement solver. This should be called after the
- /// scanning phase has finish and the playspace has been finalized.
- /// </summary>
- /// <returns></returns>
- [DllImport("SpatialUnderstanding", CallingConvention = CallingConvention.Cdecl)]
- public static extern int Solver_Init();
-
- /// <summary>
- /// Executes an object placement query.
- ///
- /// A query consists of a type a name, type, set of rules,
- /// and set of constraints.
- ///
- /// Rules may not be violated by the returned query. Possible
- /// locations that satisfy the type and rules are selected
- /// by optimizing within the constraint list.
- ///
- /// Objects placed with Solver_PlaceObject persist until removed
- /// and are considered in subsequent queries by some rules and constraints.
- /// </summary>
- /// <param name="objectName">Name of the object placement query</param>
- /// <param name="placementDefinition">The placement definition, of type ObjectPlacementDefinition</param>
- /// <param name="placementRuleCount">Length of the provided placementRules array</param>
- /// <param name="placementRules">Array of ObjectPlacementRule structures, defining the rules</param>
- /// <param name="constraintCount">Length of the provided placementConstraints array</param>
- /// <param name="placementConstraints">Array of ObjectPlacementConstraint structures, defining the constraints</param>
- /// <param name="placementResult">Pointer to an ObjectPlacementResult structure to receive the result of the query </param>
- /// <returns>Zero on failure, one on success</returns>
- [DllImport("SpatialUnderstanding", CallingConvention = CallingConvention.Cdecl)]
- public static extern int Solver_PlaceObject(
- [In, MarshalAs(UnmanagedType.LPStr)] string objectName,
- [In] IntPtr placementDefinition,// ObjectPlacementDefinition
- [In] int placementRuleCount,
- [In] IntPtr placementRules, // ObjectPlacementRule
- [In] int constraintCount,
- [In] IntPtr placementConstraints,// ObjectPlacementConstraint
- [Out] IntPtr placementResult); // ObjectPlacementResult
-
- /// <summary>
- /// Removed a solved object.
- ///
- /// Objects placed with Solver_PlaceObject persist until removed
- /// and are considered in subsequent queries by some rules and constraints.
- /// </summary>
- /// <param name="objectName"></param>
- /// <returns></returns>
- [DllImport("SpatialUnderstanding", CallingConvention = CallingConvention.Cdecl)]
- public static extern int Solver_RemoveObject(
- [In, MarshalAs(UnmanagedType.LPStr)] string objectName);
-
- /// <summary>
- /// Removed all solved object placements.
- ///
- /// Objects placed with Solver_PlaceObject persist until removed
- /// and are considered in subsequent queries by some rules and constraints.
- /// </summary>
- [DllImport("SpatialUnderstanding", CallingConvention = CallingConvention.Cdecl)]
- public static extern void Solver_RemoveAllObjects();
- }
- }