Beispiel #1
0
        public bool ClosestRayIntersection(Ray ray, Vector3 modelBase, float ignoreDistance, out Vector3 intersection)
        {
            bool intersects = false;

            intersection = Vector3.Zero;
            float minDistSquared        = float.MaxValue;
            float ignoreDistanceSquared = ignoreDistance * ignoreDistance;

            Vector3 where = Vector3.Zero;
            // Iterate over the triangles
            for (int i = 0; i < triangles.Count; i++)
            {
                TriangleVertices t = triangles[i];
                if (RayIntersectsTriangle(ray, t.Vertices, modelBase, ref where))
                {
                    float distSquared = (where - ray.Origin).LengthSquared;
                    if (distSquared > ignoreDistanceSquared && distSquared < minDistSquared)
                    {
                        minDistSquared = distSquared;
                        intersection   = where;
                        intersects     = true;
                    }
                }
            }
            return(intersects);
        }
Beispiel #2
0
        public List <TriangleVertices> Build()
        {
            List <TriangleVertices> triangles = new  List <TriangleVertices>();

            try {
                for (int ind = 0, indexSet = 0; ind < indexDataList.Count; ind++, indexSet++)
                {
                    int vertexSet = (int)indexDataVertexDataSetList[ind];

                    IndexData     indexData = (IndexData)indexDataList[indexSet];
                    OperationType opType    = operationTypes[indexSet];

                    int iterations = 0;

                    switch (opType)
                    {
                    case OperationType.TriangleList:
                        iterations = indexData.indexCount / 3;
                        break;

                    case OperationType.TriangleFan:
                    case OperationType.TriangleStrip:
                        iterations = indexData.indexCount - 2;
                        break;
                    }

                    // locate position element & the buffer to go with it
                    VertexData    vertexData = (VertexData)vertexDataList[vertexSet];
                    VertexElement posElem    =
                        vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.Position);

                    HardwareVertexBuffer posBuffer = vertexData.vertexBufferBinding.GetBuffer(posElem.Source);
                    try {
                        IntPtr posPtr = posBuffer.Lock(BufferLocking.ReadOnly);
                        IntPtr idxPtr = indexData.indexBuffer.Lock(BufferLocking.ReadOnly);

                        unsafe {
                            byte *pBaseVertex = (byte *)posPtr.ToPointer();

                            ushort *p16Idx = null;
                            uint *  p32Idx = null;

                            // counters used for pointer indexing
                            int count16 = 0;
                            int count32 = 0;

                            if (indexData.indexBuffer.Type == IndexType.Size16)
                            {
                                p16Idx = (ushort *)idxPtr.ToPointer();
                            }
                            else
                            {
                                p32Idx = (uint *)idxPtr.ToPointer();
                            }

                            float *pReal = null;

                            int triStart = triangles.Count;

                            // iterate over all the groups of 3 indices
                            triangles.Capacity = triStart + iterations;

                            uint[] index = new uint[3];

                            for (int t = 0; t < iterations; t++)
                            {
                                Vector3[]        v      = new Vector3[3];
                                TriangleVertices tri    = new TriangleVertices(v);
                                bool             broken = false;
                                for (int i = 0; i < 3; i++)
                                {
                                    // Standard 3-index read for tri list or first tri in strip / fan
                                    if (opType == OperationType.TriangleList || t == 0)
                                    {
                                        if (indexData.indexBuffer.Type == IndexType.Size32)
                                        {
                                            index[i] = p32Idx[count32++];
                                        }
                                        else
                                        {
                                            index[i] = p16Idx[count16++];
                                        }
                                    }
                                    else
                                    {
                                        // Strips and fans are formed from last 2 indexes plus the
                                        // current one for triangles after the first
                                        if (indexData.indexBuffer.Type == IndexType.Size32)
                                        {
                                            index[i] = p32Idx[i - 2];
                                        }
                                        else
                                        {
                                            index[i] = p16Idx[i - 2];
                                        }

                                        // Perform single-index increment at the last tri index
                                        if (i == 2)
                                        {
                                            if (indexData.indexBuffer.Type == IndexType.Size32)
                                            {
                                                count32++;
                                            }
                                            else
                                            {
                                                count16++;
                                            }
                                        }
                                    }

                                    // Retrieve the vertex position
                                    if (index[i] >= posBuffer.VertexCount)
                                    {
                                        log.InfoFormat("TriangleListBuilder.Build: Error: index[i] {0} is not less than posBuffer.VertexCount {1}, iteration t {2}",
                                                       index[i], posBuffer.VertexCount, t);
                                        broken = true;
                                        break;
                                    }
                                    Debug.Assert(index[i] < posBuffer.VertexCount);
                                    byte *pVertex = pBaseVertex + (index[i] * posBuffer.VertexSize);
                                    pReal  = (float *)(pVertex + posElem.Offset);
                                    v[i].x = *pReal++;
                                    v[i].y = *pReal++;
                                    v[i].z = *pReal++;
                                }
                                if (!broken)
                                {
                                    // Put the points in in counter-clockwise order
                                    if (((v[0].x - v[2].x) * (v[1].y - v[2].y) - (v[1].x - v[2].x) * (v[0].y - v[2].y)) < 0)
                                    {
                                        // Clockwise, so reverse points 1 and 2
                                        Vector3 tmp = v[1];
                                        v[1] = v[2];
                                        v[2] = tmp;
                                    }
                                    // Debug.Assert(((v[0].x - v[2].x) * (v[1].y - v[2].y) - (v[1].x - v[2].x) * (v[0].y - v[2].y)) >= 0);
                                    // Add to the list of triangles
                                    triangles.Add(new TriangleVertices(v));
                                }
                            } // for iterations
                        }     // unsafe
                    }
                    finally {
                        // unlock those buffers!
                        indexData.indexBuffer.Unlock();
                        posBuffer.Unlock();
                    }
                }
                return(triangles);
            }
            catch (Exception e) {
                log.ErrorFormat("TriangleListBuilder.Build: Exception raised during triangle building: {0}", e.Message);
                triangles.Clear();
                return(triangles);
            }
        }