private byte[] WriteShrubModels(List <Model> shrubmodels, int offset) { offset += shrubmodels.Count * 0x40; var headBytes = new byte[shrubmodels.Count * 0x40]; var bodyBytes = new List <byte>(); for (int i = 0; i < shrubmodels.Count; i++) { ShrubModel g = (ShrubModel)shrubmodels[i]; byte[] tieByte = g.SerializeHead(offset); byte[] bodBytes = g.SerializeBody(offset); bodyBytes.AddRange(bodBytes); offset += bodBytes.Length; tieByte.CopyTo(headBytes, i * 0x40); } var outBytes = new byte[headBytes.Length + bodyBytes.Count]; headBytes.CopyTo(outBytes, 0); bodyBytes.CopyTo(outBytes, headBytes.Length); return(outBytes); }
/// <summary> /// Sets an internal variable to true if the object is to be culled. /// Mobies and shrubs are culled by their drawDistance. /// Ties, terrain and shrubs are culled by frustum culling. /// </summary> public void ComputeCulling(Camera camera, bool distanceCulling, bool frustumCulling) { if (distanceCulling) { float dist = (modelObject.position - camera.position).Length; if (dist > renderDistance) { culled = true; return; } } if (frustumCulling) { if (type == RenderedObjectType.Terrain || type == RenderedObjectType.Tie || type == RenderedObjectType.Shrub) { Vector3 center = Vector3.Zero; float size = 0.0f; switch (type) { case RenderedObjectType.Terrain: TerrainFragment frag = (TerrainFragment)modelObject; center = frag.cullingCenter; size = frag.cullingSize; break; case RenderedObjectType.Shrub: ShrubModel shrub = (ShrubModel)modelObject.model; center = new Vector3(shrub.cullingX, shrub.cullingY, shrub.cullingZ); center = modelObject.rotation * center; center += modelObject.position; float shrubScale = MathF.MaxMagnitude(modelObject.scale.X, MathF.MaxMagnitude(modelObject.scale.Y, modelObject.scale.Z)); size = shrub.cullingRadius * shrubScale; break; case RenderedObjectType.Tie: TieModel tie = (TieModel)modelObject.model; center = new Vector3(tie.cullingX, tie.cullingY, tie.cullingZ); center = modelObject.rotation * center; center += modelObject.position; float tieScale = MathF.MaxMagnitude(modelObject.scale.X, MathF.MaxMagnitude(modelObject.scale.Y, modelObject.scale.Z)); size = tie.cullingRadius * tieScale; break; } for (int i = 0; i < 6; i++) { Vector3 planeNormal = camera.frustumPlaneNormals[i]; Vector3 planePoint = camera.frustumPlanePoints[i]; if (Vector3.Dot(center - planePoint, planeNormal) < -size) { culled = true; return; } } } } culled = false; }