/// <summary>
        /// Returns the hit position of a ray. If the ray doesn't intersect with any gameobject the returned position will be equal to Vector3.zero. Runs once.
        /// </summary>
        public Vector3 ReturnHitPositionFromSingleRay(Vector3 origin, Vector3 direction, float depth)
        {
            CheckEnabledStatusChanged();
            CheckMatrixChanged();

            return(OptixLibraryInterface.ReturnSingleRayHit(origin, direction, depth));
        }
        // Sends the address of every cached meshes vertex buffer as well as localToWorld transform matrix to the Optix library
        private void SendAllObjectsToOptix()
        {
            GCHandle[]  meshGCHandles           = new GCHandle[optixTransforms.Length];
            IntPtr[]    meshVertexAddresses     = new IntPtr[optixTransforms.Length];
            Matrix4x4[] meshTranslationMatrices = new Matrix4x4[optixTransforms.Length];
            int[]       meshVertexCounts        = new int[optixTransforms.Length];
            int[]       meshEnabledStatus       = new int[optixTransforms.Length];

            for (int iTransform = 0; iTransform < optixTransforms.Length; iTransform++)
            {
                // GCHandle is needed to find the memory address of the meshes vertices without doing an expensive copy
                meshGCHandles[iTransform] = GCHandle.Alloc(optixTransforms[iTransform].mesh.vertices, GCHandleType.Pinned);

                // The array pointer to the memory address of the verts
                meshVertexAddresses[iTransform] = meshGCHandles[iTransform].AddrOfPinnedObject();

                // The local to world matrix of each OptixTransform
                meshTranslationMatrices[iTransform] = optixTransforms[iTransform].transform.localToWorldMatrix;

                // The number of vertices in the mesh
                meshVertexCounts[iTransform] = optixTransforms[iTransform].mesh.vertexCount;

                // The enabled status of each gameobject (is it within the required distance or not)
                optixTransforms[iTransform].isEnabled = CheckIfTransformIsEnabled(optixTransforms[iTransform].transform);
                meshEnabledStatus[iTransform]         = optixTransforms[iTransform].isEnabled;
            }

            OptixLibraryInterface.SetAllObjectsFromUnity(optixTransforms.Length, meshVertexCounts, meshVertexAddresses, meshTranslationMatrices, meshEnabledStatus);

            // Free the GCHandles as we no longer want the GC to avoid removing our verts
            for (int iGCHandle = 0; iGCHandle < meshGCHandles.Length; iGCHandle++)
            {
                meshGCHandles[iGCHandle].Free();
            }
        }
예제 #3
0
        private unsafe void FireSensorAndUpdatePointCloud(OptixPointCloud optixPointCloud)
        {
            Vector3 *returnHitPositions;
            int      returnHitPositionCount;

            using (OptixLibraryInterface.SensorFireAndReturnHitPositions(out returnHitPositions, out returnHitPositionCount))
            {
                optixPointCloud.UpdatePositions(returnHitPositions, returnHitPositionCount);
            }
        }
        /// <summary>
        /// Checks a ray to see if it intersects with any gameobjects. Runs once.
        /// </summary>
        public bool CheckSingleRayHit(Ray ray, float depth)
        {
            CheckEnabledStatusChanged();
            CheckMatrixChanged();

            if (OptixLibraryInterface.CheckSingleRayHit(ray.origin, ray.direction, depth))
            {
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Debug.Logs the number of hit positions from single/multiple optix sensors. Runs once.
        /// </summary>
        /// <param name="optixSensors"></param>
        public int ReturnNumberOfHitPositionsSingle(OptixSensor[] optixSensors)
        {
            CheckEnabledStatusChanged();
            CheckMatrixChanged();

            this.optixSensors = optixSensors;
            OptixLibraryInterface.SetAllSensorsFromUnity(optixSensors.Length, GetBaseValuesFromSensors(optixSensors));

            int returnHitPositionCount;

            OptixLibraryInterface.SensorFireAndReturnHitCount(out returnHitPositionCount);
            return(returnHitPositionCount);
        }
        private IEnumerator CallPluginAtEndOfFrames()
        {
            while (true)
            {
                // Wait until all frame rendering is done
                yield return(new WaitForEndOfFrame());

                // Set time for the plugin
                OptixLibraryInterface.SetTimeFromUnity(Time.realtimeSinceStartup);

                // Issue a plugin event with arbitrary integer identifier.
                // The plugin can distinguish between different
                // things it needs to do based on this ID.
                // For our simple plugin, it does not matter which ID we pass here.
                GL.IssuePluginEvent(OptixLibraryInterface.GetRenderEventFunc(), 1);
            }
        }
        private void CheckOptixSensorTransformDirty()
        {
            bool updateSensors = false;

            for (int iSensor = 0; iSensor < optixSensors.Length; iSensor++)
            {
                if (optixSensors[iSensor].IsTransformDirty)
                {
                    optixSensors[iSensor].IsTransformDirty = false;
                    updateSensors = true;
                }
            }

            if (updateSensors)
            {
                OptixLibraryInterface.TranslateAllSensorsFromUnity(optixSensors.Length, GetBaseValuesFromSensors(optixSensors));
                sceneChanged = true;
            }
        }
        /// <summary>
        /// Renders the hit positions from single/multiple optix sensors into a point cloud. Runs continually until stopped by EndRaytracing().
        /// </summary>
        public void RenderPointCloudFromSensorsContinuous(OptixSensor[] optixSensors, OptixPointCloud optixPointCloud)
        {
            this.optixSensors = optixSensors;
            OptixLibraryInterface.SetAllSensorsFromUnity(optixSensors.Length, GetBaseValuesFromSensors(optixSensors));

            if (isRaytracing)
            {
                Debug.LogWarning("Attempting to start raytracing even though it is already executing.");
                return;
            }

            if (optixSensors == null)
            {
                Debug.LogWarning("Cannot have optixSensors set to null. Cancelling raytracing.");
                return;
            }

            isRaytracing = true;

            StartCoroutine(RaytracingCoroutine(optixPointCloud));
        }
        // Check if a transforms local to world matrix has changed and if it has update it in Optix
        private void CheckMatrixChanged()
        {
            List <Matrix4x4> updateMatricies = new List <Matrix4x4>();
            List <int>       updateIndices   = new List <int>();

            for (int iTransform = 0; iTransform < optixTransforms.Length; iTransform++)
            {
                if (optixTransforms[iTransform].IsDirty) // isDirty is set to true if any value within the object's transform has changed
                {
                    optixTransforms[iTransform].IsDirty = false;

                    updateMatricies.Add(optixTransforms[iTransform].transform.localToWorldMatrix);
                    updateIndices.Add(iTransform); // Pass the index of the transform so we know which matrix to update in Optix
                }
            }

            if (updateMatricies.Count > 0)  // If no enabled status' have changed, just update the matrices
            {
                OptixLibraryInterface.UpdateGameObjectMatrixFromUnity(updateMatricies.Count, updateIndices.ToArray(), updateMatricies.ToArray());
                sceneChanged = true;
            }
        }
        // Check if any of the sensors have had a value in the optix sensor component changed
        private bool CheckOptixSensorComponentDirty()
        {
            bool updateSensors = false;

            for (int iSensor = 0; iSensor < optixSensors.Length; iSensor++)
            {
                if (optixSensors[iSensor].IsComponentDirty)
                {
                    optixSensors[iSensor].IsComponentDirty = false;
                    optixSensors[iSensor].IsTransformDirty = false;
                    updateSensors = true;
                }
            }

            if (updateSensors)
            {
                OptixLibraryInterface.SetAllSensorsFromUnity(optixSensors.Length, GetBaseValuesFromSensors(optixSensors));
                sceneChanged = true;
                return(true);
            }

            return(false);
        }
        // Check if a transforms enabled status has changed and if it has update it in Optix
        private void CheckEnabledStatusChanged()
        {
            List <int> updateTransformEnabled = new List <int>();
            List <int> updateIndices          = new List <int>();

            for (int iTransform = 0; iTransform < optixTransforms.Length; iTransform++)
            {
                int transformEnabled = CheckIfTransformIsEnabled(optixTransforms[iTransform].transform);

                if (optixTransforms[iTransform].isEnabled != transformEnabled) // Check if the transforms enabled status has changed
                {
                    optixTransforms[iTransform].isEnabled = transformEnabled;
                    updateIndices.Add(iTransform);
                    updateTransformEnabled.Add(transformEnabled);
                }
            }

            if (updateTransformEnabled.Count > 0)
            {
                OptixLibraryInterface.UpdateGameObjectEnabledFromUnity(updateTransformEnabled.Count, updateIndices.ToArray(), updateTransformEnabled.ToArray());
                sceneChanged = true;
            }
        }
예제 #12
0
 public static unsafe extern bool SensorFireAndReturnHitPositions
 (
     out OptixLibraryInterface optixLibraryHandle, out Vector3 *hitPositions, out int hitPositionCount
 );