/// <summary> /// Spread flora over intersection of road. /// </summary> /// <param name="node"></param> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public override bool NewFan( Road.Intersection isect, Road.Section first, Road.Section second, List <Road.RenderObj> fans) { FBXModel model = EndModel; if (model != null) { RoadFBXRenderObj ro = new RoadFBXRenderObj(); ro.Model = model; ro.Animator = EndAnim; Matrix localToWorld = Matrix.Identity; Vector3 position = isect.Node.Position; position.Z = Terrain.GetTerrainHeightFlat(position) + isect.Node.Height; localToWorld.Translation = position; RandomizeAngle(ref localToWorld); ro.LocalToWorld = localToWorld; fans.Add(ro); return(true); } return(false); }
public void Finish(Road.Intersection isect) { AABB box = AABB.EmptyBox(); int cnt = Verts.Length; bool stretchUp = isect.Road.Generator.StretchUpEnd; for (int i = 0; i < cnt; ++i) { if (stretchUp) { float minHeight = isect.Road.Generator.MinHeight; float maxHeight = isect.Road.Generator.MaxHeight; float t = (Verts[i].pos.Z - minHeight) / (maxHeight - minHeight); float baseHeight = isect.BaseHeight(Verts[i].pos); float terrHeight = Terrain.GetTerrainHeightFlat(Verts[i].pos); Verts[i].pos.Z = terrHeight + t * (Verts[i].pos.Z + baseHeight - terrHeight); } else { if (Verts[i].pos.Z >= 0.0f) { Verts[i].pos.Z += isect.BaseHeight(Verts[i].pos); } else { Verts[i].pos.Z = Terrain.GetTerrainHeightFlat(Verts[i].pos); } } box.Union(Verts[i].pos); } sphere = box.MakeSphere(); }
/// <summary> /// Create a new post. /// </summary> /// <param name="node"></param> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public override bool NewFan( Road.Intersection isect, Road.Section first, Road.Section second, List <Road.RenderObj> fans) { return(posts.NewFan(isect, first, second, fans)); }
/// <summary> /// Create new intersection fan. /// </summary> /// <param name="node"></param> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public override bool NewFan( Road.Intersection isect, Road.Section first, Road.Section second, List <Road.RenderObj> fans) { return(NewFan(isect, new Vector2(1.0f, 0.0f), MathHelper.TwoPi, fans)); }
public void Finish(Road.Intersection isect) { AABB box = AABB.EmptyBox(); foreach (Road.RenderObj renderObj in renderObjs) { renderObj.Finish(isect); box.Union(renderObj.Sphere); } sphere = box.MakeSphere(); }
/// <summary> /// Put down a tree at the intersection. /// </summary> public override bool NewFan( Road.Intersection isect, Road.Section first, Road.Section second, List <Road.RenderObj> fans) { FBXModel model = EndModel; if (model != null) { RoadMultiRenderObj multiRo = new RoadMultiRenderObj(); Vector2 center = isect.Node.Position2d; float area = width * width * (float)Math.PI; int count = (int)Math.Ceiling(area * density); for (int i = 0; i < count; ++i) { double rndAng = BokuGame.bokuGame.rnd.NextDouble() * Math.PI * 2.0; float rndOut = (float)(BokuGame.bokuGame.rnd.NextDouble() * 2.0 - 1.0); float cos = (float)Math.Cos(rndAng); float sin = (float)Math.Sin(rndAng); Vector2 rndPos = center; rndPos.X += cos * rndOut; rndPos.Y += sin * rndOut; float height = Terrain.GetTerrainHeightFlat(rndPos); Matrix localToWorld = Matrix.CreateTranslation(rndPos.X, rndPos.Y, height); RoadFBXRenderObj ro = new RoadFBXRenderObj(); ro.Model = model; ro.Animator = EndAnim; ro.LocalToWorld = localToWorld; multiRo.RenderObjList.Add(ro); } fans.Add(multiRo); return(count > 0); } return(false); }
/// <summary> /// Generate a fan to fill out an intersection. /// </summary> /// <param name="nodeC"></param> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public override bool NewFan( Road.Intersection isect, Road.Section first, Road.Section second, List <Road.RenderObj> fans) { if ((first == null) || (second == null)) { return(NewFan(isect, new Vector2(1.0f, 0.0f), Math.PI * 2.0, fans)); } WayPoint.Node nodeC = isect.Node; WayPoint.Node node0; WayPoint.Node node1; if (!FindBend(first, second, nodeC, out node0, out node1)) { return(false); } Vector2 center = nodeC.Position2d; Vector2 firstEdge = Vector2.Normalize(node0.Position2d - center); Vector2 startRadial = new Vector2(-firstEdge.Y, firstEdge.X); double rads0 = first.EdgeAngle(nodeC) + Math.PI * 0.5; if (rads0 < 0.0) { rads0 += Math.PI * 2.0; } double rads1 = second.EdgeAngle(nodeC) - Math.PI * 0.5; if (rads1 < 0.0) { rads1 += Math.PI * 2.0; } double rads = rads1 - rads0; if (rads < 0.0) { rads += Math.PI * 2.0; } return(NewFan(isect, startRadial, rads, fans)); }
/// <summary> /// Generate a castle as an intersection. /// </summary> /// <param name="node"></param> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public override bool NewFan( Road.Intersection isect, Road.Section first, Road.Section second, List <Road.RenderObj> fans) { bool didBase = base.NewFan(isect, first, second, fans); WayPoint.Node node = isect.Node; /* * centerheight * 4.4 * height * 4.3, 2.0, 2.3, 2.3, -1.0 * width * 0.05, 0.2, 0.2, 0.3, 0.3 * */ RoadFBXRenderObj ro = null; FBXModel model = ActorManager.GetActor("Castle").Model; if (model != null) { ro = new RoadFBXRenderObj(); ro.Model = model; Matrix localToWorld = Matrix.Identity; Vector3 position = node.Position; localToWorld.Translation = position; ro.LocalToWorld = localToWorld; fans.Add(ro); return(true); } return(didBase); }
public void Finish(Road.Intersection isect) { }
/// <summary> /// Generate a new fan filling the sector defined by p0, p1, and pC as the center. /// Assumes |p0 - pC| == |p1 - pC| == radius == roadwidth/2, and that the fan goes from /// p0 to p1 counterclockwise. /// </summary> /// <param name="node">the shared node at the intersection</param> /// <param name="first">edge of start of the arc</param> /// <param name="second">edge of end of the arc</param> public abstract bool NewFan( Road.Intersection isect, Road.Section first, Road.Section second, List <Road.RenderObj> fans);
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); }