Exemple #1
0
        /// <summary>
        /// Performs an intersection test against a packet of 4 rays.
        /// </summary>
        public unsafe RTC.RayPacket4 Intersects4 <Ray>(Ray[] rays, float near = 0, float far = float.PositiveInfinity, float time = 0) where Ray : IEmbreeRay
        {
            #if DEBUG
            if (!traversalFlags.HasFlag(TraversalFlags.Packet4))
            {
                throw new InvalidOperationException("Traversal flags forbid 4-ray packet traversal");
            }
            #endif

            var p = RTC.RayInterop.Packet4;
            var a = RTC.RayInterop.Activity;

            for (var t = 0; t < 4; ++t)
            {
                if (rays[t] != null)
                {
                    a[t] = RTC.RayInterop.Active;
                }
                else
                {
                    a[t] = RTC.RayInterop.Inactive;
                    continue;
                }

                var o = rays[t].Origin;
                var d = rays[t].Direction;

                p->orgX[t] = o.X; p->orgY[t] = o.Y; p->orgZ[t] = o.Z;
                p->dirX[t] = d.X; p->dirY[t] = d.Y; p->dirZ[t] = d.Z;

                p->geomID[t] = RTC.InvalidGeometryID;
                p->primID[t] = RTC.InvalidGeometryID;
                p->instID[t] = RTC.InvalidGeometryID;

                p->time[t]  = time;
                p->tnear[t] = near;
                p->tfar[t]  = far;
            }

            RTC.Intersect4(a, scenePtr, p);

            return(*p);
        }
Exemple #2
0
        /// <summary>
        /// Commits all current instances to the scene.
        /// </summary>
        public void Commit()
        {
            foreach (var entry in instances)
            {
                var instance = entry.Value;
                instance.Geometry.Commit();

                var xtf = new float[12] // Column-major order
                {
                    instance.Transform.U.X, instance.Transform.U.Y, instance.Transform.U.Z,
                    instance.Transform.V.X, instance.Transform.V.Y, instance.Transform.V.Z,
                    instance.Transform.W.X, instance.Transform.W.Y, instance.Transform.W.Z,
                    instance.Transform.T.X, instance.Transform.T.Y, instance.Transform.T.Z
                };

                var pinned = GCHandle.Alloc(xtf, GCHandleType.Pinned); // Pin transform matrix to raw float* array
                RTC.SetTransform(scenePtr, entry.Key, RTC.MatrixLayout.ColumnMajor, pinned.AddrOfPinnedObject());
                pinned.Free();                                         // Release before checking for error
                RTC.CheckLastError();

                if (instance.Enabled)
                {
                    RTC.EnableGeometry(scenePtr, entry.Key);
                }
                else
                {
                    RTC.DisableGeometry(scenePtr, entry.Key);
                }

                RTC.CheckLastError();

                if (sceneFlags.HasFlag(SceneFlags.Dynamic))
                {
                    RTC.UpdateGeometry(scenePtr, entry.Key);
                    RTC.CheckLastError(); // static mesh?
                }
            }

            RTC.Commit(scenePtr);
            RTC.CheckLastError();
        }
Exemple #3
0
        /// <summary>
        /// Removes a geometry from this scene.
        /// </summary>
        public Boolean Remove(Geometry geometry)
        {
            CheckDisposed();

            if (geometry == null)
            {
                throw new ArgumentNullException("geometry");
            }

            if (geometryInverse.ContainsKey(geometry))
            {
                RTC.DeleteGeometry(NativePtr, geometry.ID);
                geometryMapping.Remove(geometry.ID);
                geometryInverse.Remove(geometry);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #4
0
        /// <summary>
        /// Removes an instance from this scene.
        /// </summary>
        public Boolean Remove(Instance instance)
        {
            CheckDisposed();

            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            if (instanceInverse.ContainsKey(instance))
            {
                RTC.DeleteGeometry(NativePtr, instance.ID);
                instanceMapping.Remove(instance.ID);
                instanceInverse.Remove(instance);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #5
0
        public void Update(uint geomID, IntPtr scenePtr)
        {
            if (indices.Count / 3 == triangleCount)
            {
                var indexBuffer = RTC.MapBuffer(scenePtr, geomID, RTC.BufferType.IndexBuffer);
                RTC.CheckLastError();

                Marshal.Copy(indices.ToArray(), 0, indexBuffer, indices.Count);

                RTC.UnmapBuffer(scenePtr, geomID, RTC.BufferType.IndexBuffer);
            }
            else
            {
                throw new InvalidOperationException("Index buffer length was changed.");
            }

            if (vertices.Count == vertexCount)
            {
                var vertexBuffer = RTC.MapBuffer(scenePtr, geomID, RTC.BufferType.VertexBuffer);
                RTC.CheckLastError();

                unsafe
                {
                    float *ptr = (float *)vertexBuffer;
                    foreach (var vertex in vertices)
                    {
                        *(ptr++) = vertex.X;
                        *(ptr++) = vertex.Y;
                        *(ptr++) = vertex.Z;
                        *(ptr++) = 1.0f;
                    }
                }

                RTC.UnmapBuffer(scenePtr, geomID, RTC.BufferType.VertexBuffer);
            }
            else
            {
                throw new InvalidOperationException("Vertex buffer length was changed.");
            }
        }
Exemple #6
0
        /// <summary>
        /// Sets the triangles of this triangle mesh.
        /// </summary>
        public void SetTriangles(Triangle[] triangles, int srcOffset, int dstOffset, int length)
        {
            if (triangles == null)
            {
                throw new ArgumentNullException("triangles");
            }
            else if (srcOffset < 0)
            {
                throw new ArgumentOutOfRangeException("srcOffset");
            }
            else if (dstOffset < 0)
            {
                throw new ArgumentOutOfRangeException("dstOffset");
            }
            else if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length");
            }
            else if (srcOffset + length > triangles.Length)
            {
                throw new ArgumentOutOfRangeException("srcOffset");
            }
            else if (dstOffset + length > Description.NumTriangles)
            {
                throw new ArgumentOutOfRangeException("dstOffset");
            }
            else if (length == 0)
            {
                return;
            }

            using (var triangleBuffer = new MappedBuffer <Triangle>(Parent, ID, BufferType.IndexBuffer)) {
                for (int t = 0; t < length; ++t)
                {
                    triangleBuffer[t + dstOffset] = triangles[t + srcOffset];
                }
            }

            RTC.UpdateBuffer(Parent.NativePtr, ID, BufferType.IndexBuffer);
        }
Exemple #7
0
        /// <summary>
        /// Sets the transformation matrix for this instance.
        /// </summary>
        /// <param name="transform">The transformation matrix entries.</param>
        /// <param name="layout">The layout of the matrix entries.</param>
        /// <remarks>
        /// Only the first 12 or 16 entries of the transform array are used.
        /// </remarks>
        /// <remarks>
        /// The transform should be uniform, i.e. no non-uniform scaling.
        /// </remarks>
        public unsafe void SetTransform(float[] transform, MatrixLayout layout)
        {
            if (transform == null)
            {
                throw new ArgumentNullException("transform");
            }

            switch (layout)
            {
            case MatrixLayout.ColumnMajorAligned16:
                if (transform.Length < 16)
                {
                    throw new ArgumentException("transform");
                }
                else
                {
                    break;
                }

            case MatrixLayout.ColumnMajor:
            case MatrixLayout.RowMajor:
                if (transform.Length < 12)
                {
                    throw new ArgumentException("transform");
                }
                else
                {
                    break;
                }

            default:
                throw new ArgumentException("layout");
            }

            fixed(float *xfm = transform)
            {
                RTC.SetTransform(Parent.NativePtr, ID, layout, xfm);
            }
        }
Exemple #8
0
        /// <summary>
        /// Commits all geometry within this scene.
        /// </summary>
        public void Commit()
        {
            CheckDisposed();

            RTC.Commit(NativePtr);
        }
Exemple #9
0
 /// <summary>
 /// Checks the last embree error for this devices and throws exceptions as needed
 /// </summary>
 public void CheckLastError()
 {
     RTC.CheckLastError(this.devicePtr);
 }
Exemple #10
0
        /// <summary>
        /// Creates a new raytracing device context
        /// </summary>
        /// <param name="verbose">if true embree will run inverbose mode</param>
        public Device(bool verbose = false)
        {
            string cfg = verbose ? "verbose=999" : null;

            this.devicePtr = RTC.InitEmbree(cfg);
        }
Exemple #11
0
 /// <summary>
 /// If you use the RTC interop wrapper, Embree is initialized for you.
 /// </summary>
 static RTC()
 {
     RTC.Initialize();
 }