예제 #1
0
        static protected void TrimToPlane(Vector4 plane, RoadStdRenderObj ro)
        {
            List <Int16>      idxIn  = new List <Int16>(ro.Indices);
            List <Int16>      idxOut = new List <Int16>(ro.Indices.Length);
            List <RoadVertex> verts  = new List <RoadVertex>(ro.Verts);
            List <Vector4>    planes = new List <Vector4>(1);

            planes.Add(plane);
            TrimIndexedTriList(planes, idxIn, idxOut, verts);
            ro.Indices = new Int16[idxOut.Count];
            idxOut.CopyTo(ro.Indices);
            ro.Verts = new RoadVertex[verts.Count];
            verts.CopyTo(ro.Verts);
            ro.DirtyBuffers();
        }
예제 #2
0
        /// <summary>
        /// Trim all geometry for two sections by the bisecting plane (if appropriate)
        /// </summary>
        /// <param name="plane"></param>
        public virtual bool Trim(Road.Section first, Road.Section second)
        {
            RoadStdRenderObj roFirst  = first.RenderObj as RoadStdRenderObj;
            RoadStdRenderObj roSecond = second.RenderObj as RoadStdRenderObj;

            if ((roFirst == null) || (roSecond == null))
            {
                return(false);
            }


            WayPoint.Node node0 = null;
            WayPoint.Node node1 = null;
            WayPoint.Node nodeC = null;
            if (!FindBend(first, second, out nodeC, out node0, out node1))
            {
                return(false);
            }

            Vector2 edge0 = Vector2.Normalize(node0.Position2d - nodeC.Position2d);
            Vector2 edge1 = Vector2.Normalize(node1.Position2d - nodeC.Position2d);
            float   dot   = Vector2.Dot(edge0, edge1);

            {
                float  cross = edge0.X * edge1.Y - edge0.Y * edge1.X;
                double rads  = Math.Atan2(cross, dot);
                if (rads > 0.0)
                {
                    Vector2 bisect = dot > -0.999f
                        ? Vector2.Normalize(edge0 + edge1)
                        : new Vector2(-edge0.Y, edge0.X);

                    Vector3 norm  = new Vector3(-bisect.Y, bisect.X, 0.0f);
                    float   dist  = Vector3.Dot(norm, nodeC.Position);
                    Vector4 plane = new Vector4(norm, dist);

                    TrimToPlane(-plane, roFirst);
                    TrimToPlane(plane, roSecond);

                    return(true);
                }
            }

            return(false);
        }
예제 #3
0
        private void FlushBatch(Camera camera)
        {
            if (batch.Count > 0)
            {
                GraphicsDevice device = BokuGame.bokuGame.GraphicsDevice;

                Effect          effect    = RoadStdRenderObj.Effect;
                EffectTechnique technique = RoadStdRenderObj.Technique;
                if (technique != null)
                {
                    if (wireFrame)
                    {
                        device.RasterizerState = UI2D.Shared.RasterStateWireframe;
                    }

                    RoadStdRenderObj.Parameter(RoadStdRenderObj.EffectParams.WorldViewProjMatrix).SetValue(camera.ViewProjectionMatrix);
                    RoadStdRenderObj.Parameter(RoadStdRenderObj.EffectParams.WorldMatrix).SetValue(Matrix.Identity);

                    effect.CurrentTechnique = technique;

                    for (int iPass = 0; iPass < technique.Passes.Count; ++iPass)
                    {
                        EffectPass pass = technique.Passes[iPass];

                        pass.Apply();

                        foreach (RoadStdRenderObj obj in batch)
                        {
                            obj.RenderBatch(this);
                        }
                    }

                    if (wireFrame)
                    {
                        device.RasterizerState = RasterizerState.CullCounterClockwise;
                    }
                }
                batch.Clear();
            }
        }
예제 #4
0
        /// <summary>
        /// Generate a new section.
        /// </summary>
        /// <param name="section"></param>
        public override void NewSection(Road.Section section)
        {
            section.RenderObj = null;

            RoadVertex[] verts = GenVerts(section);

            Int16[] indices = GenIndices(section);

            if ((verts.Length > 0) && (indices.Length > 0))
            {
                RoadStdRenderObj ro = new RoadStdRenderObj();

                ro.Verts       = verts;
                ro.Indices     = indices;
                ro.DiffuseTex0 = diffTex0;
                ro.DiffuseTex1 = diffTex1;
                ro.NormalTex0  = normTex0;
                ro.NormalTex1  = normTex1;
                ro.UVXfm       = uvXfm;
                ro.Shininess   = Shininess;

                section.RenderObj = ro;
            }
        }
예제 #5
0
 /// <summary>
 /// Add a renderable to the batching list pending FlushBatch.
 /// </summary>
 /// <param name="obj"></param>
 public void AddBatch(RoadStdRenderObj obj)
 {
     batch.Add(obj);
 }
예제 #6
0
        protected virtual bool NewFan(
            Road.Intersection isect,
            Vector2 startRadial,
            double rads,
            List <Road.RenderObj> fans)
        {
            Road   road       = isect.Road;
            int    numRadials = (int)Math.Ceiling(rads / road.RadStep);
            double radStep    = rads / numRadials;

            Vector2 center = isect.Node.Position2d;

            int vertsPerRadial = VertsPerStep / 2;
            int numVerts       = (numRadials + 1) * vertsPerRadial + 1;

            RoadVertex[] verts = new RoadVertex[numVerts];

            Vector3 terrNormal = Vector3.UnitZ;

            AABB box = AABB.EmptyBox();

            int iVert = 0;

            for (int iRadial = 0; iRadial <= numRadials; ++iRadial)
            {
                double ang = radStep * iRadial;
                float  cos = (float)Math.Cos(ang);
                float  sin = (float)Math.Sin(ang);

                Vector2 radial = new Vector2(startRadial.X * cos - startRadial.Y * sin,
                                             startRadial.X * sin + startRadial.Y * cos);

                for (int iOut = 0; iOut < vertsPerRadial; ++iOut)
                {
                    float width  = widthTable[iOut];
                    float height = heightTable[iOut];

                    float arc = (float)(ang * width);

                    RoadVertex vtx = new RoadVertex();
                    Vector2    pos = center + width * radial;

                    //float baseHeight = isect.BaseHeight(pos);
                    //height += baseHeight;

                    vtx.pos.X = pos.X;
                    vtx.pos.Y = pos.Y;
                    vtx.pos.Z = height;

                    box.Union(vtx.pos);

                    vtx.norm = VtxNormal(terrNormal, radial, iOut);

                    vtx.uv.X      = arc;
                    vtx.uv.Y      = distTable[iOut];
                    vtx.texSelect = TexSelect(iOut);

                    verts[iVert++] = vtx;
                }
            }

            float centerBaseHeight = 0.0f; //  isect.BaseHeight(center);
            float heightAtCenter   = centerHeight + centerBaseHeight;

            RoadVertex last = new RoadVertex();

            last.pos.X = center.X;
            last.pos.Y = center.Y;
            last.pos.Z = heightAtCenter;

            box.Union(last.pos);

            last.norm = terrNormal;

            last.uv.X      = 0.0f;
            last.uv.Y      = 0.0f;
            last.texSelect = TexSelect(0);

            int centerIdx = iVert++;

            verts[centerIdx] = last;

            Debug.Assert(iVert == numVerts);

            // First step per radial is a single tri,
            // then the rest of the steps are quads
            int quadsPerRadial = vertsPerRadial - 1;

            int numTris = 0;

            if (!skipTable[0])
            {
                numTris += numRadials;

                numTris += numRadials * (quadsPerRadial - numSkips) * 2;
            }
            else
            {
                numTris += numRadials * (quadsPerRadial - (numSkips - 1)) * 2;
            }
            Int16[] indices = new Int16[numTris * 3];

            int nextRad = vertsPerRadial;
            int nextOut = 1;
            int baseVtx = 0;
            int idx     = 0;

            for (int iRadial = 0; iRadial < numRadials; ++iRadial)
            {
                if (!skipTable[0])
                {
                    indices[idx++] = (Int16)(baseVtx);
                    indices[idx++] = (Int16)(centerIdx);
                    indices[idx++] = (Int16)(baseVtx + nextRad);
                }

                for (int iOut = 0; iOut < quadsPerRadial; iOut++)
                {
                    if (!skipTable[iOut + 1])
                    {
                        indices[idx++] = (Int16)(baseVtx + iOut + nextRad);
                        indices[idx++] = (Int16)(baseVtx + iOut + nextRad + nextOut);
                        indices[idx++] = (Int16)(baseVtx + iOut);

                        indices[idx++] = (Int16)(baseVtx + iOut);
                        indices[idx++] = (Int16)(baseVtx + iOut + nextRad + nextOut);
                        indices[idx++] = (Int16)(baseVtx + iOut + nextOut);
                    }
                }
                baseVtx += nextRad;
            }
            Debug.Assert(idx == numTris * 3);

            RoadStdRenderObj ro = null;

            if ((verts.Length > 0) && (indices.Length > 0))
            {
                ro = new RoadStdRenderObj();

                ro.Verts       = verts;
                ro.Indices     = indices;
                ro.DiffuseTex0 = diffTex0;
                ro.DiffuseTex1 = diffTex1;
                ro.NormalTex0  = normTex0;
                ro.NormalTex1  = normTex1;
                ro.UVXfm       = uvXfm;
                ro.Shininess   = Shininess;
                ro.Sphere      = box.MakeSphere();

                fans.Add(ro);

                return(true);
            }
            return(false);
        }