Exemple #1
0
        public KdTree(int maxDepth, int maxLeavePrimitives, SceneDatabase sceneDatabase)
        {
            mMaxNumOfPrimitives = maxLeavePrimitives;
            mMaxDepth           = maxDepth;

            //
            List <RTGeometry> allGeom  = new List <RTGeometry>();
            Vector3           worldMin = new Vector3(float.MaxValue);
            Vector3           worldMax = new Vector3(float.MinValue);

            // we need to compute the compute the world min/max
            for (int i = 0; i < sceneDatabase.GetNumGeom(); i++)
            {
                RTGeometry g = sceneDatabase.GetGeom(i);
                allGeom.Add(g);
                worldMin = Vector3.Min(worldMin, g.Min);
                worldMax = Vector3.Max(worldMax, g.Max);
            }

            int rootDepth = 0;

            mRoot = new KdTreeNode(worldMin, worldMax, new KdTreeAxis(rootDepth), allGeom);

            BuildKDTree(mRoot, rootDepth, allGeom);
        }
        /// <summary>
        /// Diffuse color lookup: if texture mapped, scale the texture value by mKd
        /// </summary>
        /// <param name="database"></param>
        /// <param name="rec"></param>
        /// <returns></returns>
        public Vector3 GetDiffuse(SceneDatabase database, IntersectionRecord rec)
        {
            Vector3 result = mKd.AttributeValue();

            if (mKd.IsTextureMapped())
            {
                result *= mKd.AttributeLookup(database, rec);
            }
            return(result);
        }
        public RTCore(RTWindow w, String cmdFile, ContentManager meshLoader)
        {
            mRTWindows = w;

            mSceneDatabase = new SceneDatabase();
            mParser = new CommandFileParser(cmdFile, meshLoader, w.StatusArea(), this, mSceneDatabase);
            mCurrentX = mCurrentY = 0;

            //
            FirstTimeInit();
        }
        public RTCore(RTWindow w, String cmdFile, ContentManager meshLoader)
        {
            mRTWindows = w;

            mSceneDatabase = new SceneDatabase();
            mParser        = new CommandFileParser(cmdFile, meshLoader, w.StatusArea(), this, mSceneDatabase);
            mCurrentX      = mCurrentY = 0;

            //
            FirstTimeInit();
        }
        /// <summary>
        /// Transparency look up: if mapped, scales Avg(RBG) by transparency
        /// </summary>
        /// <param name="database"></param>
        /// <param name="rec"></param>
        /// <returns></returns>
        public float GetTransparency(SceneDatabase database, IntersectionRecord rec)
        {
            float result = mTransparency.AttributeValue();

            if (mTransparency.IsTextureMapped())
            {
                Vector3 v = mTransparency.AttributeLookup(database, rec);
                result *= ((v.X + v.Y + v.Z) / 3f);
            }
            return(result);
        }
Exemple #6
0
        /// <summary>
        /// Percentage of the light that is visible from the visiblePt
        /// </summary>
        /// <param name="visiblePt"></param>
        /// <param name="exceptGeomIndex">this geometry can never block the light (geomIndex of the visiblePt)</param>
        /// <param name="database"></param>
        /// <returns></returns>
        public virtual float PercentVisible(Vector3 visiblePt, int exceptGeomIndex, SceneDatabase sceneDatabase)
        {
            IntersectionRecord rec = new IntersectionRecord(DistanceToLight(visiblePt));
            Ray r = Ray.CrateRayFromPtDir(visiblePt, GetNormalizedDirection(visiblePt));

            bool blocked = false;
            int  count   = 0;

            while ((!blocked) && (count < sceneDatabase.GetNumGeom()))
            {
                if (count != exceptGeomIndex)
                {
                    blocked = sceneDatabase.GetGeom(count).Intersect(r, rec);
                }
                count++;
            }
            return(blocked ? 0f : 1f);
        }
        /// <summary>
        /// How much of the spot light is visible from the visiblePt
        /// </summary>
        /// <param name="visiblePt"></param>
        /// <param name="exceptGeomIndex">this geometry can never block the light (geomIndex of the visiblePt)</param>
        /// <param name="database"></param>
        /// <returns></returns>
        public override float PercentVisible(Vector3 visiblePt, int exceptGeomIndex, SceneDatabase sceneDatabase)
        {
            float cosAlpha = 0f;
            bool  canIllum = InLightCone(visiblePt, ref cosAlpha);
            float percent  = 0f;

            if (canIllum)
            {
                if (mUseDepthMap)
                {
                    percent = SampleDepthMap(visiblePt, exceptGeomIndex);
                }
                else
                {
                    percent = base.PercentVisible(visiblePt, exceptGeomIndex, sceneDatabase);
                }
            }
            return(percent);
        }
        /// <summary>
        /// Normal vector lookup, if texture mapped, replaces the intersection record's normal vector!
        /// </summary>
        /// <param name="database"></param>
        /// <param name="rec"></param>
        /// <returns></returns>
        public Vector3 GetNormal(SceneDatabase database, IntersectionRecord rec)
        {
            Vector3 result;

            if (mNormal.IsTextureMapped())
            {
                result = mNormal.AttributeLookup(database, rec);
                if (Vector3.Dot(result, rec.NormalAtIntersect) < 0)
                {
                    result = -result;
                }
                rec.SetNormalAtIntersection(result);
            }
            else
            {
                result = rec.NormalAtIntersect;
            }

            return(result);
        }
        private void AddLights(RayTracer_552.SceneDatabase rtScene)
        {
            UWB_XNAGraphicsDevice.m_TheAPI.LightManager.ResetAllLights();
            for (int l = 0; l < rtScene.GetNumLights(); l++)
            {
                RTLight      lgt      = rtScene.GetLight(l);
                Vector4      useColor = new Vector4(lgt.GetColor(new Vector3(0, 0, 0)), 1f);
                UWB_XNALight theLight = null;

                if (lgt.GetLightSourceType() == RTLightType.RTLightSourceType.RTLightSourceTypeDirection)
                {
                    theLight = UWB_XNAGraphicsDevice.m_TheAPI.LightManager.CreateDirectionalLight();
                }
                else if (lgt.GetLightSourceType() == RTLightType.RTLightSourceType.RTLightSourceTypeSpot)
                {
                    theLight = UWB_XNAGraphicsDevice.m_TheAPI.LightManager.CreateSpotLight();
                }
                else
                {
                    theLight = UWB_XNAGraphicsDevice.m_TheAPI.LightManager.CreatePointLight();
                }

                theLight.Ambient     = Vector4.Zero;
                theLight.Diffuse     = useColor;
                theLight.Specular    = useColor;
                theLight.Position    = lgt.GetLightPosition();
                theLight.Direction   = -lgt.GetNormalizedDirection(Vector3.Zero);
                theLight.Color       = useColor;
                theLight.Attenuation = new Vector3(1f, 0.0f, 0.0f);
                theLight.Range       = 10000f;
                theLight.SwitchOnLight();

                UWB_Primitive prim = CreateSphereMesh();
                SetMeshMaterial(prim, rtScene.GetMaterial(0));
                float scale = 0.25f;
                CreateNode(lgt.GetLightPosition(), scale, scale, scale, prim);
            }
        }
        public KdTree(int maxDepth, int maxLeavePrimitives, SceneDatabase sceneDatabase)
        {
            mMaxNumOfPrimitives = maxLeavePrimitives;
            mMaxDepth = maxDepth;

            //
            List<RTGeometry> allGeom = new List<RTGeometry>();
            Vector3 worldMin = new Vector3(float.MaxValue);
            Vector3 worldMax = new Vector3(float.MinValue);

            // we need to compute the compute the world min/max
            for (int i = 0; i < sceneDatabase.GetNumGeom(); i++)
            {
                RTGeometry g = sceneDatabase.GetGeom(i);
                allGeom.Add(g);
                worldMin = Vector3.Min(worldMin, g.Min);
                worldMax = Vector3.Max(worldMax, g.Max);
            }

            int rootDepth = 0;
            mRoot = new KdTreeNode(worldMin, worldMax, new KdTreeAxis(rootDepth), allGeom);

            BuildKDTree(mRoot, rootDepth, allGeom);
        }
        public CommandFileParser(String cmdFile, ContentManager meshLoader, System.Windows.Forms.TextBox statusArea, RTCore rt, SceneDatabase scene)
        {
            mStatusArea = statusArea;

            mFullPath = System.IO.Path.GetFullPath(System.IO.Path.GetDirectoryName(cmdFile));

            mParser = new XmlTextReader(cmdFile);
            mParser.WhitespaceHandling = WhitespaceHandling.None;

            ParserRead();
            while (!IsEndElement("RayTracer_552"))
            {
                if (IsElement() && (!IsElement("RayTracer_552")) )
                {
                    if (IsElement("camera"))
                    {
                        RTCamera c = new RTCamera(this);
                        rt.SetCamera(c);
                        ParserRead();
                    }
                    else if (IsElement("sphere"))
                    {
                        RTSphere s = new RTSphere(this);
                        scene.AddGeom(s);
                        ParserRead();
                    }
                    else if (IsElement("rectangle"))
                    {
                        RTRectangle r = new RTRectangle(this);
                        scene.AddGeom(r);
                        ParserRead();
                    }
                    else if (IsElement("triangle"))
                    {
                        RTTriangle t = new RTTriangle(this);
                        scene.AddGeom(t);
                        ParserRead();
                    }
                    else if (IsElement("mesh"))
                    {
                        RTTriangle.ParseMeshForTriangles(this, meshLoader, scene);
                        ParserRead();
                    }
                    else if (IsElement("imagespec"))
                    {
                        ImageSpec s = new ImageSpec(this);
                        rt.SetImageSpec(s);
                        ParserRead();
                    }
                    else if (IsElement("rtspec"))
                    {
                        rt.Parse(this);
                        ParserRead();
                    }
                    else if (IsElement("material"))
                    {
                        RTMaterial m = new RTMaterial(this);
                        scene.AddMaterial(m);
                        ParserRead();
                    }
                    else if (IsElement("light"))
                    {
                        RTLight l = new RTLight(this);
                        scene.AddLight(l);
                        ParserRead();
                    }
                    else if (IsElement("texture"))
                    {
                        RTTexture t = new RTTexture(this);
                        scene.AddTexture(t);
                        ParserRead();
                    }
                    else
                        ParserError("Main Parser:");
                }
                else
                    ParserRead();
            }
            mParser.Close();

            if (!mHasError)
                mStatusArea.Text = "Parsing Completed!";
        }
 public override void InitializeLight(SceneDatabase sceneDatabase)
 {
     InitDepthMap(sceneDatabase);
 }
        internal void AddRTScene(RayTracer_552.RTCamera c, RayTracer_552.SceneDatabase rtScene)
        {
            UWB_Primitive prim;

            NewSceneDatabase();
            SceneResource <RTGeometry> allGeom = rtScene.GetAllGeom();

            for (int i = 0; i < allGeom.Count; i++)
            {
                RTGeometry g = (RTGeometry)allGeom.ResourceLookup(i);
                switch (g.GeomType())
                {
                case RTGeometry.RTGeometryType.Sphere:
                    RTSphere s = (RTSphere)g;
                    prim = CreateSphereMesh();
                    SetMeshMaterial(prim, rtScene.GetMaterial(s.GetMaterialIndex()));
                    float scale = s.Radius / 2f;
                    CreateNode(s.Center, scale, scale, scale, prim);
                    break;

                case RTGeometry.RTGeometryType.Rectangle:
                    RTRectangle r = (RTRectangle)g;
                    prim = CreateRectangle(r);
                    SetMeshMaterial(prim, rtScene.GetMaterial(r.GetMaterialIndex()));
                    UWB_SceneNode node = CreateNode(r.GetCenter(), r.GetUSize() / 2f, 1f, r.GetVSize() / 2f, prim);
                    // now rotate the y-vector of node to point towards r.Normal;
                    float dot = (float)Math.Abs(Vector3.Dot(Vector3.UnitY, r.GetNormal()));
                    if (dot < 0.9999f)
                    {
                        float   angle = (float)Math.Acos(dot);
                        Vector3 axis  = Vector3.Cross(Vector3.UnitY, r.GetNormal());
                        axis.Normalize();
                        Quaternion    q  = Quaternion.CreateFromAxisAngle(axis, angle);
                        UWB_XFormInfo xf = node.getXFormInfo();
                        xf.SetRotationQuat(q);
                        node.setXFormInfo(xf);
                    }
                    break;

                case RTGeometry.RTGeometryType.Triangle:
                    RTTriangle t = (RTTriangle)g;
                    Vector3[]  v = t.GetVertices();
                    prim = new UWB_PrimitiveTriangle(v[0], v[1], v[2]);
                    prim.EnableLighting(true);
                    prim.EnableTexturing(false);
                    SetMeshMaterial(prim, rtScene.GetMaterial(t.GetMaterialIndex()));
                    CreateNode(Vector3.Zero, 1f, 1f, 1f, prim);
                    break;
                }
            }
            AddCamera(c);
            AddLights(rtScene);

            // to show ray list
            mShownRayX  = mShownRayY = 0;
            mRaysToShow = new UWB_PrimitiveList();

            mDebugInfo = new UWB_SceneNode();
            mDebugInfo.setPrimitive(mRaysToShow);
            mDebugInfo.insertChildNode(mPixelsToShow.GetAllPixels());
            mDebugInfo.insertChildNode(mPixelInWorld.GetAllPixels());
        }
 public float PercentVisible(Vector3 visiblePt, int exceptGeomIndex, SceneDatabase sceneDatabase)
 {
     return(mLight.PercentVisible(visiblePt, exceptGeomIndex, sceneDatabase));
 }
 public override void InitializeLight(SceneDatabase sceneDatabase)
 {
     InitDepthMap(sceneDatabase);
 }
Exemple #16
0
        public CommandFileParser(String cmdFile, ContentManager meshLoader, System.Windows.Forms.TextBox statusArea, RTCore rt, SceneDatabase scene)
        {
            mStatusArea = statusArea;

            mFullPath = System.IO.Path.GetFullPath(System.IO.Path.GetDirectoryName(cmdFile));

            mParser = new XmlTextReader(cmdFile);
            mParser.WhitespaceHandling = WhitespaceHandling.None;

            ParserRead();
            while (!IsEndElement("RayTracer_552"))
            {
                if (IsElement() && (!IsElement("RayTracer_552")))
                {
                    if (IsElement("camera"))
                    {
                        RTCamera c = new RTCamera(this);
                        rt.SetCamera(c);
                        ParserRead();
                    }
                    else if (IsElement("sphere"))
                    {
                        RTSphere s = new RTSphere(this);
                        scene.AddGeom(s);
                        ParserRead();
                    }
                    else if (IsElement("rectangle"))
                    {
                        RTRectangle r = new RTRectangle(this);
                        scene.AddGeom(r);
                        ParserRead();
                    }
                    else if (IsElement("triangle"))
                    {
                        RTTriangle t = new RTTriangle(this);
                        scene.AddGeom(t);
                        ParserRead();
                    }
                    else if (IsElement("mesh"))
                    {
                        RTTriangle.ParseMeshForTriangles(this, meshLoader, scene);
                        ParserRead();
                    }
                    else if (IsElement("imagespec"))
                    {
                        ImageSpec s = new ImageSpec(this);
                        rt.SetImageSpec(s);
                        ParserRead();
                    }
                    else if (IsElement("rtspec"))
                    {
                        rt.Parse(this);
                        ParserRead();
                    }
                    else if (IsElement("material"))
                    {
                        RTMaterial m = new RTMaterial(this);
                        scene.AddMaterial(m);
                        ParserRead();
                    }
                    else if (IsElement("light"))
                    {
                        RTLight l = new RTLight(this);
                        scene.AddLight(l);
                        ParserRead();
                    }
                    else if (IsElement("texture"))
                    {
                        RTTexture t = new RTTexture(this);
                        scene.AddTexture(t);
                        ParserRead();
                    }
                    else
                    {
                        ParserError("Main Parser:");
                    }
                }
                else
                {
                    ParserRead();
                }
            }
            mParser.Close();

            if (!mHasError)
            {
                mStatusArea.Text = "Parsing Completed!";
            }
        }
        private int mRes = 128; // depth map resolution is Res x Res

        #endregion Fields

        #region Methods

        private void InitDepthMap(SceneDatabase sceneDatabase)
        {
            if (null != mDepthMap)
                return; // done

            // remember!! mDireciton is L, or a vector from Visible point to the light.
            // Here we want direction from light source towards the scene
            Vector3 useDir = -mDirection;

            // 1. Find a Up direction
            //         guess up direction to be (0, 1, 0), if view direction is also this,
            //         use (1, 0, 0) as view direction
            Vector3 up = Vector3.UnitY;
            if (Math.Abs(Vector3.Dot(up, useDir)) > 0.99999)
                up = Vector3.UnitX;

            // 2. define Orthonormal base
            Vector3 sideV = Vector3.Cross(up, useDir);
            up = Vector3.Cross(useDir, sideV);
            sideV.Normalize();
            up.Normalize();

            // 3. compute the depth map image plane,
            //    define the image plane to be located at ... a distance of kDepthImageDist away
            Vector3 ptOnImage = mPosition + kDepthImageDist * useDir;

            // 4. compute depth map image size
            float halfImageSize = kDepthImageDist * (float)Math.Tan(mOuterAngle/2f);

            // 5. Compute the 4 vertices the defines the depth map
            Vector3[] v = new Vector3[4];
            v[0] = ptOnImage - halfImageSize * up - halfImageSize * sideV;
            v[1] = ptOnImage - halfImageSize * up + halfImageSize * sideV;
            v[2] = ptOnImage + halfImageSize * up + halfImageSize * sideV;
            v[3] = ptOnImage + halfImageSize * up - halfImageSize * sideV;

            // 6. create a Geometry that represents the map
            // ** Be caureful **!!
            //     RTRectangle uses v[0] as the origin for texture lookup
            //     we _MUST_ follow the same in order to take advante of GetUV() function!
            mDepthMapGeom = new RTRectangle(v);

            // 7. Now allocate memory for the actual map
            mDepthMap = new float[mRes][];
            mGeomID = new int[mRes][];
            for (int i = 0; i<mRes; i++) {
                mDepthMap[i] = new float[mRes];
                mGeomID[i] = new int[mRes];
            }

            // now, trace rays through each of the pixels in the depth map and record the depth and geomID
            float pixelSize = halfImageSize / (0.5f * mRes);
            Vector3 upPixelVector = pixelSize * up;
            Vector3 sidePixelVector = pixelSize * sideV;
            for (int y = 0; y < mRes; y++) {
                Vector3 yDisp = v[0] + (y+0.5f) * upPixelVector;
                for (int x = 0; x < mRes; x++) {
                    Vector3 pixelPos = ((x+0.5f) * sidePixelVector) + yDisp;
                    Ray r = new Ray(mPosition, pixelPos);
                    IntersectionRecord rec = new IntersectionRecord();

                    for (int i = 0; i < sceneDatabase.GetNumGeom(); i++)
                    {
                        RTGeometry g = sceneDatabase.GetGeom(i);
                        g.Intersect(r, rec);
                    }
                    mDepthMap[x][y] = rec.HitDistance;
                    // closes intersection distance, any object that is
                    // further away from the light than this distance is in the shadow of this light
                    mGeomID[x][y] = rec.GeomIndex;
                    // this object can never be in shadow, becuase it is the closest to the light!
                }
            }
        }
 /// <summary>
 /// Looks up attribute from the texture table! NO ERROR CHECKINGG! If mTextureIndex is invalid, this function will crash!!
 /// </summary>
 /// <param name="database"></param>
 /// <param name="rec"></param>
 /// <returns></returns>
 public Vector3 AttributeLookup(SceneDatabase database, IntersectionRecord rec)
 {
     return(database.GetTexture(mTextureIndex).TextureLookup(rec, database.GetGeom(rec.GeomIndex)));
 }
 public float PercentVisible(Vector3 visiblePt, int exceptGeomIndex, SceneDatabase sceneDatabase)
 {
     return mLight.PercentVisible(visiblePt, exceptGeomIndex, sceneDatabase);
 }
Exemple #20
0
        static public void ParseMeshForTriangles(CommandFileParser parser, ContentManager meshLoader, SceneDatabase sceneDatabase)
        {
            String meshFileName = null;
            int    material     = 0;

            // has xform?
            bool   hasTransform = false;
            Matrix xform        = Matrix.Identity;
            Matrix invT         = Matrix.Identity;

            #region Parse the command file
            parser.ParserRead();
            while (!parser.IsEndElement("mesh"))
            {
                if (parser.IsElement() && (!parser.IsElement("mesh")))
                {
                    if (parser.IsElement("filename"))
                    {
                        meshFileName = parser.ReadString();
                    }
                    else if (parser.IsElement("xform"))
                    {
                        hasTransform = true;
                        xform        = ParseTransform(parser);
                    }
                    else if (parser.IsElement("material"))
                    {
                        material = parser.ReadInt();
                    }
                    else
                    {
                        parser.ParserError("mesh");
                    }
                }
                else
                {
                    parser.ParserRead();
                }
            }
            #endregion

            if (null == meshFileName)
            {
                parser.ParserError("No Mesh filename!");
                return;
            }

            if (hasTransform)
            {
                invT = Matrix.Transpose(Matrix.Invert(xform));
            }

            Model     model             = meshLoader.Load <Model>(meshFileName);
            Byte[]    localVertexBuffer = null;
            Int32[]   localIndexBuffer  = null;
            Vector3[] vertexPosition    = null;
            Vector3[] normalAtVertex    = null;
            Vector2[] uvAtVertex        = null;
            bool      hasPosition       = false;
            bool      hasNormal         = false;
            bool      hasUV             = false;

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    int numIndices  = part.IndexBuffer.IndexCount;   // total number of localIndexBuffer in the buffer
                    int numVertices = part.VertexBuffer.VertexCount; // total number of vertices in the buffer

                    #region Only need to load/translate these buffers once!
                    // *** REALLY? ***
                    if (null == localIndexBuffer)
                    {
                        vertexPosition = new Vector3[numVertices];
                        normalAtVertex = new Vector3[numVertices];
                        uvAtVertex     = new Vector2[numVertices];

                        localIndexBuffer = LoadIndexBuffer(part);

                        int numBytes = numVertices * part.VertexBuffer.VertexDeclaration.VertexStride;
                        localVertexBuffer = new Byte[numBytes];
                        part.VertexBuffer.GetData <Byte>(localVertexBuffer);

                        VertexElement[] vertexElements = part.VertexBuffer.VertexDeclaration.GetVertexElements();

                        int bufferOffset = 0;
                        #region parse each vertex
                        // now get all the vertices
                        for (int vertCount = 0; vertCount < numVertices; vertCount++)
                        {   // parse through the elements
                            bufferOffset = vertCount * part.VertexBuffer.VertexDeclaration.VertexStride;

                            hasUV = false; // do this for each vertex
                            for (int e = 0; e < vertexElements.Length; e++)
                            {
                                switch (vertexElements[e].VertexElementUsage)
                                {
                                case VertexElementUsage.Position:
                                    hasPosition = true;
                                    // Vertex position
                                    int vertexByteOffset = bufferOffset + vertexElements[e].Offset;
                                    vertexPosition[vertCount].X = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); vertexByteOffset += 4;
                                    vertexPosition[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); vertexByteOffset += 4;
                                    vertexPosition[vertCount].Z = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset);
                                    break;

                                case VertexElementUsage.Normal:
                                    hasNormal = true;
                                    int normalByteOffset = bufferOffset + vertexElements[e].Offset;
                                    normalAtVertex[vertCount].X = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); normalByteOffset += 4;
                                    normalAtVertex[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); normalByteOffset += 4;
                                    normalAtVertex[vertCount].Z = BitConverter.ToSingle(localVertexBuffer, normalByteOffset);
                                    break;

                                case VertexElementUsage.TextureCoordinate:
                                    if (!hasUV)
                                    {      // if more than one defined, will only use the first one
                                        hasUV = true;
                                        int uvByteOffset = bufferOffset + vertexElements[e].Offset;
                                        uvAtVertex[vertCount].X = BitConverter.ToSingle(localVertexBuffer, uvByteOffset); uvByteOffset += 4;
                                        uvAtVertex[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, uvByteOffset);
                                    }
                                    break;
                                    // ignore all other cases
                                } // the switch on usage for parsing
                            }     // for of vertexElements
                        }         // for each vertex
                        #endregion


                        #region compute the transform for each vertex
                        // now do the transform
                        if (hasTransform)
                        {
                            for (int v = 0; v < numVertices; v++)
                            {
                                vertexPosition[v] = Vector3.Transform(vertexPosition[v], xform);
                            }
                            if (hasNormal)
                            {
                                for (int v = 0; v < numVertices; v++)
                                {
                                    normalAtVertex[v] = Vector3.Transform(normalAtVertex[v], invT);
                                    normalAtVertex[v] = Vector3.Normalize(normalAtVertex[v]);
                                }
                            }
                        }
                        #endregion
                    }
                    #endregion

                    // now start working on this particular part ...
                    int startIndex = part.StartIndex;

                    int vertexOffset = part.VertexOffset;

                    // start from part.StartIndex
                    int numTriangles = part.PrimitiveCount;

                    #region create the triangles
                    // now all vertice are stored.
                    // let's create the Triangles
                    for (int nthT = 0; nthT < numTriangles; nthT++)
                    {
                        Vector3[] vertices = new Vector3[3];
                        Vector2[] uv       = new Vector2[3];
                        Vector3[] normals  = null;
                        if (hasNormal)
                        {
                            normals = new Vector3[3];
                        }

                        #region copy vertex info
                        int indexOffset = startIndex + (nthT * 3);
                        for (int i = 0; i < 3; i++)
                        {
                            int index = vertexOffset + localIndexBuffer[indexOffset + i];
                            vertices[i] = vertexPosition[index];
                            uv[i]       = uvAtVertex[index];
                            if (hasNormal)
                            {
                                normals[i] = normalAtVertex[index];
                            }
                        }
                        #endregion

                        // now create the new triangle
                        // watch out for bad triangles!!
                        if (hasPosition)
                        {
                            if (!hasNormal)
                            {
                                normalAtVertex = null;
                            }
                            Vector3 aVec = vertices[1] - vertices[0];
                            if (aVec.LengthSquared() > float.Epsilon)
                            {
                                Vector3 bVec = vertices[2] - vertices[0];
                                if (bVec.LengthSquared() > float.Epsilon)
                                {
                                    RTTriangle t = new RTTriangle(vertices, normals, uv, material);
                                    sceneDatabase.AddGeom(t);
                                }
                            }
                        }
                    }
                    #endregion
                }
            }
        }
 public void InitializeLight(SceneDatabase sceneDataBase)
 {
     mLight.InitializeLight(sceneDataBase);
 }
 public void InitializeLight(SceneDatabase sceneDataBase)
 {
     mLight.InitializeLight(sceneDataBase);
 }
        public static void ParseMeshForTriangles(CommandFileParser parser, ContentManager meshLoader, SceneDatabase sceneDatabase)
        {
            String meshFileName = null;
            int material = 0;

            // has xform?
            bool hasTransform = false;
            Matrix xform = Matrix.Identity;
            Matrix invT = Matrix.Identity;

            #region Parse the command file
            parser.ParserRead();
            while (!parser.IsEndElement("mesh"))
            {
                if (parser.IsElement() && (!parser.IsElement("mesh")))
                {
                    if (parser.IsElement("filename"))
                    {
                        meshFileName = parser.ReadString();
                    }
                    else if (parser.IsElement("xform"))
                    {
                        hasTransform = true;
                        xform = ParseTransform(parser);
                    }
                    else if (parser.IsElement("material"))
                        material = parser.ReadInt();
                    else
                        parser.ParserError("mesh");
                }
                else
                    parser.ParserRead();
            }
            #endregion

            if (null == meshFileName)
            {
                parser.ParserError("No Mesh filename!");
                return;
            }

            if (hasTransform)
                invT = Matrix.Transpose(Matrix.Invert(xform));

            Model model = meshLoader.Load<Model>(meshFileName);
            Byte[] localVertexBuffer = null;
            Int32[] localIndexBuffer = null;
            Vector3[] vertexPosition = null;
            Vector3[] normalAtVertex = null;
            Vector2[] uvAtVertex = null;
            bool hasPosition = false;
            bool hasNormal = false;
            bool hasUV = false;

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    int numIndices = part.IndexBuffer.IndexCount;  // total number of localIndexBuffer in the buffer
                    int numVertices = part.VertexBuffer.VertexCount; // total number of vertices in the buffer

                    #region Only need to load/translate these buffers once!
                    // *** REALLY? ***
                    if (null == localIndexBuffer)
                    {
                        vertexPosition = new Vector3[numVertices];
                        normalAtVertex = new Vector3[numVertices];
                        uvAtVertex = new Vector2[numVertices];

                        localIndexBuffer = LoadIndexBuffer(part);

                        int numBytes = numVertices * part.VertexBuffer.VertexDeclaration.VertexStride;
                        localVertexBuffer = new Byte[numBytes];
                        part.VertexBuffer.GetData<Byte>(localVertexBuffer);

                        VertexElement[] vertexElements = part.VertexBuffer.VertexDeclaration.GetVertexElements();

                        int bufferOffset = 0;
                        #region parse each vertex
                        // now get all the vertices
                        for (int vertCount = 0; vertCount < numVertices; vertCount++)
                        {   // parse through the elements
                            bufferOffset = vertCount * part.VertexBuffer.VertexDeclaration.VertexStride;

                            hasUV = false; // do this for each vertex
                            for (int e = 0; e < vertexElements.Length; e++)
                            {
                                switch (vertexElements[e].VertexElementUsage)
                                {
                                    case VertexElementUsage.Position:
                                        hasPosition = true;
                                        // Vertex position
                                        int vertexByteOffset = bufferOffset + vertexElements[e].Offset;
                                        vertexPosition[vertCount].X = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); vertexByteOffset += 4;
                                        vertexPosition[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); vertexByteOffset += 4;
                                        vertexPosition[vertCount].Z = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset);
                                        break;
                                    case VertexElementUsage.Normal:
                                        hasNormal = true;
                                        int normalByteOffset = bufferOffset + vertexElements[e].Offset;
                                        normalAtVertex[vertCount].X = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); normalByteOffset += 4;
                                        normalAtVertex[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); normalByteOffset += 4;
                                        normalAtVertex[vertCount].Z = BitConverter.ToSingle(localVertexBuffer, normalByteOffset);
                                        break;
                                    case VertexElementUsage.TextureCoordinate:
                                        if (!hasUV)
                                        {  // if more than one defined, will only use the first one
                                            hasUV = true;
                                            int uvByteOffset = bufferOffset + vertexElements[e].Offset;
                                            uvAtVertex[vertCount].X = BitConverter.ToSingle(localVertexBuffer, uvByteOffset); uvByteOffset += 4;
                                            uvAtVertex[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, uvByteOffset);
                                        }
                                        break;
                                    // ignore all other cases
                                } // the switch on usage for parsing
                            } // for of vertexElements
                        } // for each vertex
                        #endregion

                        #region compute the transform for each vertex
                        // now do the transform
                        if (hasTransform)
                        {
                            for (int v = 0; v < numVertices; v++)
                                vertexPosition[v] = Vector3.Transform(vertexPosition[v], xform);
                            if (hasNormal)
                                for (int v = 0; v < numVertices; v++)
                                {
                                    normalAtVertex[v] = Vector3.Transform(normalAtVertex[v], invT);
                                    normalAtVertex[v] = Vector3.Normalize(normalAtVertex[v]);
                                }
                        }
                        #endregion
                    }
                    #endregion

                    // now start working on this particular part ...
                    int startIndex = part.StartIndex;

                    int vertexOffset = part.VertexOffset;

                    // start from part.StartIndex
                    int numTriangles = part.PrimitiveCount;

                    #region create the triangles
                    // now all vertice are stored.
                    // let's create the Triangles
                    for (int nthT = 0; nthT < numTriangles; nthT++)
                    {
                        Vector3[] vertices = new Vector3[3];
                        Vector2[] uv = new Vector2[3];
                        Vector3[] normals = null;
                        if (hasNormal)
                            normals = new Vector3[3];

                        #region copy vertex info
                        int indexOffset = startIndex + (nthT * 3);
                        for (int i = 0; i < 3; i++)
                        {
                            int index = vertexOffset + localIndexBuffer[indexOffset + i];
                            vertices[i] = vertexPosition[index];
                            uv[i] = uvAtVertex[index];
                            if (hasNormal)
                                normals[i] = normalAtVertex[index];
                        }
                        #endregion

                        // now create the new triangle
                        // watch out for bad triangles!!
                        if (hasPosition)
                        {
                            if (!hasNormal)
                                normalAtVertex = null;
                            Vector3 aVec = vertices[1] - vertices[0];
                            if (aVec.LengthSquared() > float.Epsilon)
                            {
                                Vector3 bVec = vertices[2] - vertices[0];
                                if (bVec.LengthSquared() > float.Epsilon)
                                {
                                    RTTriangle t = new RTTriangle(vertices, normals, uv, material);
                                    sceneDatabase.AddGeom(t);
                                }
                            }
                        }
                    }
                    #endregion
                }
            }
        }
Exemple #24
0
 /// <summary>
 /// Initialization of light after the entire scene has been read in
 /// </summary>
 /// <param name="sceneDatabase"></param>
 public virtual void InitializeLight(SceneDatabase sceneDatabase)
 {
 }
        /// <summary>
        /// How much of the spot light is visible from the visiblePt
        /// </summary>
        /// <param name="visiblePt"></param>
        /// <param name="exceptGeomIndex">this geometry can never block the light (geomIndex of the visiblePt)</param>
        /// <param name="database"></param>
        /// <returns></returns>
        public override float PercentVisible(Vector3 visiblePt, int exceptGeomIndex, SceneDatabase sceneDatabase)
        {
            float cosAlpha = 0f;
            bool canIllum = InLightCone(visiblePt, ref cosAlpha);
            float percent = 0f;

            if (canIllum)
            {
                if (mUseDepthMap)
                {
                    percent = SampleDepthMap(visiblePt, exceptGeomIndex);
                }
                else
                    percent = base.PercentVisible(visiblePt, exceptGeomIndex, sceneDatabase);
            }
            return percent;
        }
Exemple #26
0
        private const float kDepthImageDist = 1f; // depth map image plane distance from the light source

        private void InitDepthMap(SceneDatabase sceneDatabase)
        {
            if (null != mDepthMap)
            {
                return; // done
            }
            // remember!! mDireciton is L, or a vector from Visible point to the light.
            // Here we want direction from light source towards the scene
            Vector3 useDir = -mDirection;

            // 1. Find a Up direction
            //         guess up direction to be (0, 1, 0), if view direction is also this,
            //         use (1, 0, 0) as view direction
            Vector3 up = Vector3.UnitY;

            if (Math.Abs(Vector3.Dot(up, useDir)) > 0.99999)
            {
                up = Vector3.UnitX;
            }


            // 2. define Orthonormal base
            Vector3 sideV = Vector3.Cross(up, useDir);

            up = Vector3.Cross(useDir, sideV);
            sideV.Normalize();
            up.Normalize();

            // 3. compute the depth map image plane,
            //    define the image plane to be located at ... a distance of kDepthImageDist away
            Vector3 ptOnImage = mPosition + kDepthImageDist * useDir;

            // 4. compute depth map image size
            float halfImageSize = kDepthImageDist * (float)Math.Tan(mOuterAngle / 2f);

            // 5. Compute the 4 vertices the defines the depth map
            Vector3[] v = new Vector3[4];
            v[0] = ptOnImage - halfImageSize * up - halfImageSize * sideV;
            v[1] = ptOnImage - halfImageSize * up + halfImageSize * sideV;
            v[2] = ptOnImage + halfImageSize * up + halfImageSize * sideV;
            v[3] = ptOnImage + halfImageSize * up - halfImageSize * sideV;

            // 6. create a Geometry that represents the map
            // ** Be caureful **!!
            //     RTRectangle uses v[0] as the origin for texture lookup
            //     we _MUST_ follow the same in order to take advante of GetUV() function!
            mDepthMapGeom = new RTRectangle(v);

            // 7. Now allocate memory for the actual map
            mDepthMap = new float[mRes][];
            mGeomID   = new int[mRes][];
            for (int i = 0; i < mRes; i++)
            {
                mDepthMap[i] = new float[mRes];
                mGeomID[i]   = new int[mRes];
            }

            // now, trace rays through each of the pixels in the depth map and record the depth and geomID
            float   pixelSize       = halfImageSize / (0.5f * mRes);
            Vector3 upPixelVector   = pixelSize * up;
            Vector3 sidePixelVector = pixelSize * sideV;

            for (int y = 0; y < mRes; y++)
            {
                Vector3 yDisp = v[0] + (y + 0.5f) * upPixelVector;
                for (int x = 0; x < mRes; x++)
                {
                    Vector3            pixelPos = ((x + 0.5f) * sidePixelVector) + yDisp;
                    Ray                r        = new Ray(mPosition, pixelPos);
                    IntersectionRecord rec      = new IntersectionRecord();

                    for (int i = 0; i < sceneDatabase.GetNumGeom(); i++)
                    {
                        RTGeometry g = sceneDatabase.GetGeom(i);
                        g.Intersect(r, rec);
                    }
                    mDepthMap[x][y] = rec.HitDistance;
                    // closes intersection distance, any object that is
                    // further away from the light than this distance is in the shadow of this light
                    mGeomID[x][y] = rec.GeomIndex;
                    // this object can never be in shadow, becuase it is the closest to the light!
                }
            }
        }