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(); }
/// <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); }
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(); } }
/// <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; } }
/// <summary> /// Add a renderable to the batching list pending FlushBatch. /// </summary> /// <param name="obj"></param> public void AddBatch(RoadStdRenderObj obj) { batch.Add(obj); }
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); }