public Box3f ToWorldBox(Box3f box) { Frame3f f = new Frame3f(box.Center, box.AxisX, box.AxisY, box.AxisZ); Frame3f fS = ToWorldFrame(f); return(new Box3f(fS.Origin, fS.X, fS.Y, fS.Z, GetSceneScale() * box.Extent)); }
public AxisAlignedBox3f GetPrintMeshesBounds(bool bPrecise) { AxisAlignedBox3f b = AxisAlignedBox3f.Empty; foreach (PrintMeshSO so in PrintMeshes) { if (SceneUtil.IsVisible(so) == false) { continue; } if (bPrecise) { var xform = SceneTransforms.ObjectToSceneXForm(so); foreach (Vector3d v in so.Mesh.Vertices()) { b.Contain((Vector3f)xform.TransformP(v)); } } else { Box3f sobox = so.GetBoundingBox(CoordSpace.SceneCoords); if (sobox.Volume > 0) { foreach (Vector3d v in sobox.VerticesItr()) { b.Contain(v); } } } } return(b); }
private void CreateParticles(Box3f exclusion) { int numX = (int)(Bounds.Width / Diameter); int numY = (int)(Bounds.Height / Diameter); int numZ = (int)(Bounds.Depth / Diameter); Positions = new List <Vector3f>(); for (int z = 0; z < numZ; z++) { for (int y = 0; y < numY; y++) { for (int x = 0; x < numX; x++) { Vector3f pos = new Vector3f(); pos.x = Diameter * x + Bounds.Min.x + Spacing; pos.y = Diameter * y + Bounds.Min.y + Spacing; pos.z = Diameter * z + Bounds.Min.z + Spacing; if (!exclusion.Contains(pos)) { Positions.Add(pos); } } } } }
public static float SqrDistanceFromBox(Box3f box, Vector3f p) { float sqDist = 0.0f; if (p.x < box.Min.x) { sqDist += (box.Min.x - p.x) * (box.Min.x - p.x); } if (p.x > box.Max.x) { sqDist += (p.x - box.Max.x) * (p.x - box.Max.x); } if (p.y < box.Min.y) { sqDist += (box.Min.y - p.y) * (box.Min.y - p.y); } if (p.y > box.Max.y) { sqDist += (p.y - box.Max.y) * (p.y - box.Max.y); } if (p.z < box.Min.z) { sqDist += (box.Min.z - p.z) * (box.Min.z - p.z); } if (p.z > box.Max.z) { sqDist += (p.z - box.Max.z) * (p.z - box.Max.z); } return(sqDist); }
public virtual void Setup() { // push history stream, so that we can do undo/redo internal to tool, // that will not end up in external history push_history_stream(); // clear selection here so that multi-select GroupSO goes away, otherwise // when we copy frmaes below, they are relative to that GroupSO, and things move inputSelection = new List <SceneObject>(Scene.Selected); set_allow_selection_changes(true); Scene.ClearSelection(); set_allow_selection_changes(false); objects = new List <TargetObject>(); foreach (var so in InputSOs) { TargetObject o = new TargetObject(); o.SO = so; o.InputMeshV = new DVector <double>(o.SO.Mesh.VerticesBuffer); if (o.SO.Mesh.HasVertexNormals) { o.InputMeshN = new DVector <float>(o.SO.Mesh.NormalsBuffer); } o.objFrame = so.GetLocalFrame(CoordSpace.ObjectCoords); o.sceneFrame = so.GetLocalFrame(CoordSpace.SceneCoords); o.sceneToObjUnitScale = SceneTransforms.SceneToObject(o.SO, 1.0f); o.localScale = so.GetLocalScale(); o.localBounds = so.GetLocalBoundingBox(); Box3f sb = so.GetBoundingBox(CoordSpace.SceneCoords); o.sceneBounds = sb.ToAABB(); o.curLocalScale = o.localScale; o.curSceneFrame = o.sceneFrame; objects.Add(o); } if (false && objects.Count == 1) { originalDims = objects[0].localBounds; } else { originalDims = objects[0].sceneBounds; for (int k = 1; k < objects.Count; ++k) { originalDims.Contain(objects[k].sceneBounds); } } currentDims = originalDims; sharedOriginS = (Vector3f)originalDims.Point(0, -1, 0); initialize_parameters(); }
public void MarkAsStatic(Box3f bounds) { for (int i = 0; i < NumParticles; i++) { if (bounds.Contains(Positions[i])) { StaticConstraints.Add(new StaticConstraint3d(this, i)); } } }
/// <summary> /// input box is in Object (local) coords of so, apply all intermediate /// transforms to get it to Scene coords /// </summary> public static Box3f ObjectToScene(SceneObject so, Box3f box) { Frame3f f = new Frame3f(box.Center, box.AxisX, box.AxisY, box.AxisZ); Frame3f fS = ObjectToScene(so, f); // [TODO] could maybe figure out nonuniform scaling by applying this to // box-corner-pt vector instead, and taking dots before/after? float scale = ObjectToSceneV(so, Vector3f.OneNormalized).Length; return(new Box3f(fS.Origin, fS.X, fS.Y, fS.Z, scale * box.Extent)); }
internal MCPTable2(MCP mcp, int index, AssetLoader loader) : base(mcp, index) { var reader = loader.Reader; Unknowns.ReadInt32s(reader, 1); loader.Expect(index); int count1 = reader.ReadInt32(); int offset1 = reader.ReadInt32(); Table1U1 = mcp.GetTable1Slice(count1, offset1); Box = loader.ReadCheckedAbsoluteBox3f(); }
public void UpdateBounds() { Vector3f min = new Vector3f(float.PositiveInfinity); Vector3f max = new Vector3f(float.NegativeInfinity); for (int i = 0; i < NumParticles; i++) { min.Min(Positions[i]); max.Max(Positions[i]); } min -= ParticleRadius; max += ParticleRadius; Bounds = new Box3f(min, max); }
public static bool BoxContainsPoint(Box3f box, Vector3f p) { if (p.x > box.Max.x || p.x < box.Min.x) { return(false); } if (p.y > box.Max.y || p.y < box.Min.y) { return(false); } if (p.z > box.Max.z || p.z < box.Min.z) { return(false); } return(true); }
public static bool BoxIntersectsBox(Box3f box0, Box3f box1) { if (box0.Max.x < box1.Min.x || box0.Min.x > box1.Max.x) { return(false); } if (box0.Max.y < box1.Min.y || box0.Min.y > box1.Max.y) { return(false); } if (box0.Max.z < box1.Min.z || box0.Min.z > box1.Max.z) { return(false); } return(true); }
/// <summary> /// input box is in Scene, apply all intermediate inverse /// transforms to get it to local frame of SO /// </summary> public static Box3f SceneToObject(SceneObject so, Box3f box) { Frame3f f = new Frame3f(box.Center, box.AxisX, box.AxisY, box.AxisZ); Frame3f fL = SceneToObject(so, f); // [TODO] make more efficient... Vector3f dv = box.Extent.x * box.AxisX + box.Extent.y * box.AxisY + box.Extent.z * box.AxisZ; Frame3f fCornerS = new Frame3f(box.Center + dv); Frame3f fCornerL = SceneToObject(so, fCornerS); Vector3f dvL = fCornerL.Origin - fL.Origin; Vector3f scales = new Vector3f( dvL.Dot(fCornerL.X) / box.Extent.x, dvL.Dot(fCornerL.Y) / box.Extent.y, dvL.Dot(fCornerL.Z) / box.Extent.z); return(new Box3f(fL.Origin, fL.X, fL.Y, fL.Z, scales * box.Extent)); }
public void CreateBoundary(float radius, float density) { InnerBounds = new Box3f(-8, 4, 0, 10, -2, 4); //new Box3f(-8, 8, 0, 10, -2, 4); OuterBounds = InnerBounds; float thickness = 1.2f; OuterBounds.Min -= new Vector3f(radius * 2 * thickness); OuterBounds.Max += new Vector3f(radius * 2 * thickness); ParticleSource source = new ParticlesFromBounds(radius, OuterBounds, InnerBounds); Boundary = new FluidBoundary3d(source, radius, density, Matrix4x4f.Identity); CreateBoundaryVisualize(); }
virtual public AxisAlignedBox3f GetLocalBoundingBox() { if (vChildren.Count == 0) { return(new AxisAlignedBox3f(Vector3f.Zero, 0.5f)); } Box3d combine = vChildren[0].GetBoundingBox(CoordSpace.SceneCoords); for (int k = 1; k < vChildren.Count; ++k) { Box3d childbox = vChildren[k].GetBoundingBox(CoordSpace.SceneCoords); combine = Box3d.Merge(ref combine, ref childbox); } Box3f boxLocal = SceneTransforms.SceneToObject(this, (Box3f)combine); return(boxLocal.ToAABB()); }
/// <summary> /// Compute AABB of scene in given space. Note that this will *not* be the same box /// in world space as in scene space. /// This computation ignores SOs with zero volume. /// </summary> public AxisAlignedBox3f GetBoundingBox(CoordSpace eSpace, bool bIncludeBoundsObjects) { if (eSpace == CoordSpace.ObjectCoords) { eSpace = CoordSpace.SceneCoords; } AxisAlignedBox3f b = AxisAlignedBox3f.Empty; foreach (SceneObject so in SceneObjects) { Box3f sobox = so.GetBoundingBox(eSpace); if (sobox.Volume > 0) { foreach (Vector3d v in sobox.VerticesItr()) { b.Contain(v); } } } if (bIncludeBoundsObjects) { AxisAlignedBox3f sceneBounds = UnityUtil.GetGeometryBoundingBox(BoundsObjects, true); if (sceneBounds.Volume > 0) { if (eSpace == CoordSpace.WorldCoords) { for (int k = 0; k < 8; ++k) { b.Contain(ToWorldP(sceneBounds.Corner(k))); } } else { b.Contain(sceneBounds); } } } if (b.Volume == 0) { b = new AxisAlignedBox3f(1.0f); } return(b); }
public static Vector3f ClosestPointOnBox(Box3f box, Vector3f p) { Vector3f c; if (p.x < box.Min.x) { c.x = box.Min.x; } else if (p.x > box.Max.x) { c.x = box.Max.x; } else { c.x = p.x; } if (p.y < box.Min.y) { c.y = box.Min.y; } else if (p.y > box.Max.y) { c.y = box.Max.y; } else { c.y = p.y; } if (p.z < box.Min.z) { c.z = box.Min.z; } else if (p.z > box.Max.z) { c.z = box.Max.z; } else { c.z = p.z; } return(c); }
virtual public Box3f GetBoundingBox(CoordSpace eSpace) { Box3f box = new Box3f(GetLocalBoundingBox()); if (eSpace == CoordSpace.ObjectCoords) { return(box); } else if (eSpace == CoordSpace.SceneCoords) { return(SceneTransforms.ObjectToScene(this, box)); } else { box = SceneTransforms.ObjectToScene(this, box); return(GetScene().ToWorldBox(box)); } }
public static void DrawBounds(Camera camera, Color color, Box3f bounds, Matrix4x4f localToWorld) { if (camera == null) { return; } bounds.GetCorners(m_corners4f); IList <Vector4> verts = Vertices(8); for (int i = 0; i < 8; i++) { verts[i] = MathConverter.ToVector4(localToWorld * m_corners4f[i]); } DrawVerticesAsLines(camera, color, verts, m_cube); }
internal ModelBone(FolderAsset folder, int index, AssetLoader loader) : base(folder, index, loader) { var reader = loader.Reader; Position = reader.ReadVector3f(); Name = reader.ReadStringzAtUInt32(Encoding); Angle = Angle3.Radians(reader.ReadVector3f()); parentIndex = reader.ReadInt16(); firstChildIndex = reader.ReadInt16(); Scale = reader.ReadVector3f(); nextSiblingIndex = reader.ReadInt16(); previousSiblingIndex = reader.ReadInt16(); var min = reader.ReadVector3f(); Unknowns.ReadInt32s(reader, 1); // 0 or 1 var max = reader.ReadVector3f(); Bounds = new Box3f(min, max); reader.RequireZeroes(4 * 13); }
public void CreateFluid(float radius, float density) { //To make less particles decrease the size of the bounds or increase the radius. //Make sure fluid bounds fits inside the boundrys bounds. FluidBounds = new Box3f(-8, 0, 0, 8, -2, 2);//new Box3f(-7, 6, 1, 7, -2, 4); FluidParticlesWithConstraint source = new FluidParticlesWithConstraint(radius, FluidBounds, Boundary.NumParticles); System.Random rnd = new System.Random(0); Body = new FluidBody3d(source, radius, density, Matrix4x4f.Identity); Body.Dampning = 0.0f; Body.AddBoundry(Boundary); Body.RandomizePositions(rnd, radius * 0.01f); Body.RandomizePositionOrder(rnd); Debug.Log(Body.NumParticles); CreateFluidVisualize(); }
public static bool BoxIntersectsCircle(Box3f box, Sphere3f sphere) { if (sphere.Center.x - sphere.Radius > box.Max.x || sphere.Center.x + sphere.Radius < box.Min.x) { return(false); } if (sphere.Center.y - sphere.Radius > box.Max.y || sphere.Center.y + sphere.Radius < box.Min.y) { return(false); } if (sphere.Center.z - sphere.Radius > box.Max.z || sphere.Center.z + sphere.Radius < box.Min.z) { return(false); } return(true); }
public static void RecenterAboveOrigin(FScene scene, SceneObject so, bool bInteractive) { Frame3f curFrameO = so.GetLocalFrame(CoordSpace.ObjectCoords); AxisAlignedBox3f bounds = so.GetLocalBoundingBox(); Box3f box = new Box3f(bounds); box = curFrameO.FromFrame(ref box); AxisAlignedBox3f boundsS = box.ToAABB(); Vector3f c = boundsS.Center - 0.5f * boundsS.Height * Vector3f.AxisY; Vector3f dt = -c; if (dt.MaxAbs > MathUtil.ZeroTolerancef) { Frame3f newFrameO = curFrameO.Translated(dt); TransformSOChange change = new TransformSOChange(so, curFrameO, newFrameO, CoordSpace.ObjectCoords); scene.History.PushChange(change, false); if (bInteractive) { scene.History.PushInteractionCheckpoint(); } } }
public ParticlesFromBounds(float spacing, Box3f bounds, Box3f exclusion) : base(spacing) { Bounds = bounds; CreateParticles(exclusion); }
public ParticlesFromBounds(float spacing, Box3f bounds) : base(spacing) { Bounds = bounds; CreateParticles(); }
/// <summary> /// Returns new tree with all points deleted which are inside. /// </summary> public static IPointCloudNode Delete(this IPointCloudNode root, Func <IPointCloudNode, bool> isNodeFullyInside, Func <IPointCloudNode, bool> isNodeFullyOutside, Func <V3d, bool> isPositionInside, Storage storage, CancellationToken ct, int splitLimit ) { if (root == null) { return(null); } var f = root as FilteredNode; if (f != null) { var filter = f.Filter as ISpatialFilter; if (filter != null) { bool remove(IPointCloudNode n) => filter.IsFullyInside(n) && isNodeFullyInside(n); bool keep(IPointCloudNode n) => filter.IsFullyOutside(n) || isNodeFullyOutside(n); bool contains(V3d pt) => filter.Contains(pt) && isPositionInside(pt); var res = f.Node.Delete(remove, keep, contains, storage, ct, splitLimit); return(FilteredNode.Create(res, f.Filter)); } else { throw new NotImplementedException("cannot delete on PointCloud with non-spatial filter"); } } if (isNodeFullyInside(root)) { return(null); } if (isNodeFullyOutside(root)) { if (!root.IsMaterialized) { root = root.Materialize(); } return(root); } if (root.IsLeaf) { var ps = root.HasPositions ? new List <V3f>() : null; var cs = root.HasColors ? new List <C4b>() : null; var ns = root.HasNormals ? new List <V3f>() : null; var js = root.HasIntensities ? new List <int>() : null; var ks = root.HasClassifications ? new List <byte>() : null; var oldPs = root.Positions?.Value; var oldCs = root.Colors?.Value; var oldNs = root.Normals?.Value; var oldIs = root.Intensities?.Value; var oldKs = root.Classifications?.Value; var bbabs = Box3d.Invalid; var bbloc = Box3f.Invalid; for (var i = 0; i < oldPs.Length; i++) { var pabs = (V3d)oldPs[i] + root.Center; if (!isPositionInside(pabs)) { if (oldPs != null) { ps.Add(oldPs[i]); } if (oldCs != null) { cs.Add(oldCs[i]); } if (oldNs != null) { ns.Add(oldNs[i]); } if (oldIs != null) { js.Add(oldIs[i]); } if (oldKs != null) { ks.Add(oldKs[i]); } bbabs.ExtendBy(pabs); bbloc.ExtendBy(oldPs[i]); } } if (ps.Count == 0) { return(null); } var psa = ps.ToArray(); var newId = Guid.NewGuid(); var kd = psa.Length < 1 ? null : psa.BuildKdTree(); Guid psId = Guid.NewGuid(); Guid kdId = kd != null?Guid.NewGuid() : Guid.Empty; Guid csId = cs != null?Guid.NewGuid() : Guid.Empty; Guid nsId = ns != null?Guid.NewGuid() : Guid.Empty; Guid isId = js != null?Guid.NewGuid() : Guid.Empty; Guid ksId = ks != null?Guid.NewGuid() : Guid.Empty; storage.Add(psId, psa); var data = ImmutableDictionary <Durable.Def, object> .Empty .Add(Durable.Octree.NodeId, newId) .Add(Durable.Octree.Cell, root.Cell) .Add(Durable.Octree.BoundingBoxExactGlobal, bbabs) .Add(Durable.Octree.BoundingBoxExactLocal, bbloc) .Add(Durable.Octree.PositionsLocal3fReference, psId) .Add(Durable.Octree.PointCountCell, ps.Count) .Add(Durable.Octree.PointCountTreeLeafs, (long)ps.Count) .Add(Durable.Octree.MaxTreeDepth, 0) .Add(Durable.Octree.MinTreeDepth, 0) ; if (kd != null) { storage.Add(kdId, kd.Data); data = data.Add(Durable.Octree.PointRkdTreeFDataReference, kdId); } if (cs != null) { storage.Add(csId, cs.ToArray()); data = data.Add(Durable.Octree.Colors4bReference, csId); } if (ns != null) { storage.Add(nsId, ns.ToArray()); data = data.Add(Durable.Octree.Normals3fReference, nsId); } if (js != null) { storage.Add(isId, js.ToArray()); data = data.Add(Durable.Octree.Intensities1iReference, isId); } if (ks != null) { storage.Add(ksId, ks.ToArray()); data = data.Add(Durable.Octree.Classifications1bReference, ksId); } // MinTreeDepth MaxTreeDepth SubNodeIds?? return(new PointSetNode(data, storage, writeToStore: true)); } else { var subnodes = root.Subnodes.Map((r) => r?.Value?.Delete(isNodeFullyInside, isNodeFullyOutside, isPositionInside, storage, ct, splitLimit)); var pointCountTree = subnodes.Sum((n) => n != null ? n.PointCountTree : 0); if (pointCountTree == 0) { return(null); } else if (pointCountTree <= splitLimit) { var psabs = root.HasPositions ? new List <V3d>() : null; var cs = root.HasColors ? new List <C4b>() : null; var ns = root.HasNormals ? new List <V3f>() : null; var js = root.HasIntensities ? new List <int>() : null; var ks = root.HasClassifications ? new List <byte>() : null; foreach (var c in subnodes) { if (c != null) { MergeExtensions.CollectEverything(c, psabs, cs, ns, js, ks); } } Debug.Assert(psabs.Count == pointCountTree); var psa = psabs.MapToArray((p) => (V3f)(p - root.Center)); var kd = psa.Length < 1 ? null : psa.BuildKdTree(); Guid psId = Guid.NewGuid(); Guid kdId = kd != null?Guid.NewGuid() : Guid.Empty; Guid csId = cs != null?Guid.NewGuid() : Guid.Empty; Guid nsId = ns != null?Guid.NewGuid() : Guid.Empty; Guid isId = js != null?Guid.NewGuid() : Guid.Empty; Guid ksId = ks != null?Guid.NewGuid() : Guid.Empty; var bbabs = new Box3d(psabs); var newId = Guid.NewGuid(); storage.Add(psId, psa); var data = ImmutableDictionary <Durable.Def, object> .Empty .Add(Durable.Octree.NodeId, newId) .Add(Durable.Octree.Cell, root.Cell) .Add(Durable.Octree.BoundingBoxExactGlobal, bbabs) .Add(Durable.Octree.BoundingBoxExactLocal, (Box3f)(bbabs - root.Center)) .Add(Durable.Octree.PositionsLocal3fReference, psId) .Add(Durable.Octree.PointCountCell, (int)pointCountTree) .Add(Durable.Octree.PointCountTreeLeafs, pointCountTree) .Add(Durable.Octree.MaxTreeDepth, 0) .Add(Durable.Octree.MinTreeDepth, 0) ; if (kd != null) { storage.Add(kdId, kd.Data); data = data.Add(Durable.Octree.PointRkdTreeFDataReference, kdId); } if (cs != null) { storage.Add(csId, cs.ToArray()); data = data.Add(Durable.Octree.Colors4bReference, csId); } if (ns != null) { storage.Add(nsId, ns.ToArray()); data = data.Add(Durable.Octree.Normals3fReference, nsId); } if (js != null) { storage.Add(isId, js.ToArray()); data = data.Add(Durable.Octree.Intensities1iReference, isId); } if (ks != null) { storage.Add(ksId, ks.ToArray()); data = data.Add(Durable.Octree.Classifications1bReference, ksId); } // MinTreeDepth MaxTreeDepth SubNodeIds?? return(new PointSetNode(data, storage, writeToStore: true)); } else { var bbabs = new Box3d(subnodes.Map(n => n != null ? n.BoundingBoxExactGlobal : Box3d.Invalid)); var subids = subnodes.Map(n => n != null ? n.Id : Guid.Empty); var maxDepth = subnodes.Max(n => n != null ? n.MaxTreeDepth + 1 : 0); var minDepth = subnodes.Min(n => n != null ? n.MinTreeDepth + 1 : 0); var octreeSplitLimit = splitLimit; var fractions = LodExtensions.ComputeLodFractions(subnodes); var counts = LodExtensions.ComputeLodCounts(octreeSplitLimit, fractions); // generate LoD data ... var needsCs = subnodes.Any(x => x != null ? x.HasColors : false); var needsNs = subnodes.Any(x => x != null ? x.HasNormals : false); var needsIs = subnodes.Any(x => x != null ? x.HasIntensities : false); var needsKs = subnodes.Any(x => x != null ? x.HasClassifications : false); var subcenters = subnodes.Map(x => x?.Center); var lodPs = LodExtensions.AggregateSubPositions(counts, octreeSplitLimit, root.Center, subcenters, subnodes.Map(x => x?.Positions?.Value)); var lodCs = needsCs ? LodExtensions.AggregateSubArrays(counts, octreeSplitLimit, subnodes.Map(x => x?.Colors?.Value)) : null; var lodIs = needsIs ? LodExtensions.AggregateSubArrays(counts, octreeSplitLimit, subnodes.Map(x => x?.Intensities?.Value)) : null; var lodKs = needsKs ? LodExtensions.AggregateSubArrays(counts, octreeSplitLimit, subnodes.Map(x => x?.Classifications?.Value)) : null; var lodNs = needsNs ? LodExtensions.AggregateSubArrays(counts, octreeSplitLimit, subnodes.Map(x => x?.Normals?.Value)) : null; var lodKd = lodPs.Length < 1 ? null : lodPs.BuildKdTree(); Guid psId = Guid.NewGuid(); Guid kdId = lodKd != null?Guid.NewGuid() : Guid.Empty; Guid csId = lodCs != null?Guid.NewGuid() : Guid.Empty; Guid nsId = lodNs != null?Guid.NewGuid() : Guid.Empty; Guid isId = lodIs != null?Guid.NewGuid() : Guid.Empty; Guid ksId = lodKs != null?Guid.NewGuid() : Guid.Empty; var newId = Guid.NewGuid(); storage.Add(psId, lodPs); var bbloc = new Box3f(lodPs); // be inner node var data = ImmutableDictionary <Durable.Def, object> .Empty .Add(Durable.Octree.SubnodesGuids, subids) .Add(Durable.Octree.NodeId, newId) .Add(Durable.Octree.Cell, root.Cell) .Add(Durable.Octree.BoundingBoxExactGlobal, bbabs) .Add(Durable.Octree.BoundingBoxExactLocal, bbloc) .Add(Durable.Octree.PositionsLocal3fReference, psId) .Add(Durable.Octree.PointCountCell, lodPs.Length) .Add(Durable.Octree.PointCountTreeLeafs, pointCountTree) .Add(Durable.Octree.MaxTreeDepth, maxDepth) .Add(Durable.Octree.MinTreeDepth, minDepth) ; if (lodKd != null) { storage.Add(kdId, lodKd.Data); data = data.Add(Durable.Octree.PointRkdTreeFDataReference, kdId); } if (lodCs != null) { storage.Add(csId, lodCs); data = data.Add(Durable.Octree.Colors4bReference, csId); } if (lodNs != null) { storage.Add(nsId, lodNs); data = data.Add(Durable.Octree.Normals3fReference, nsId); } if (lodIs != null) { storage.Add(isId, lodIs); data = data.Add(Durable.Octree.Intensities1iReference, isId); } if (lodKs != null) { storage.Add(ksId, lodKs); data = data.Add(Durable.Octree.Classifications1bReference, ksId); } // MinTreeDepth MaxTreeDepth SubNodeIds?? return(new PointSetNode(data, storage, writeToStore: true)); } } }
public PointSetNode ToPointSetCell(Storage storage, bool isTemporaryImportNode) { var center = new V3d(_centerX, _centerY, _centerZ); V3f[] ps = null; C4b[] cs = null; V3f[] ns = null; int[] js = null; byte[] ks = null; if (_ia != null) { var allPs = _octree.m_ps; var count = _ia.Count; ps = new V3f[count]; for (var i = 0; i < count; i++) { ps[i] = (V3f)(allPs[_ia[i]] - center); } if (_octree.m_cs != null) { var allCs = _octree.m_cs; cs = new C4b[count]; for (var i = 0; i < count; i++) { cs[i] = allCs[_ia[i]]; } } if (_octree.m_ns != null) { var allNs = _octree.m_ns; ns = new V3f[count]; for (var i = 0; i < count; i++) { ns[i] = allNs[_ia[i]]; } } if (_octree.m_is != null) { var allIs = _octree.m_is; js = new int[count]; for (var i = 0; i < count; i++) { js[i] = allIs[_ia[i]]; } } if (_octree.m_ks != null) { var allKs = _octree.m_ks; ks = new byte[count]; for (var i = 0; i < count; i++) { ks[i] = allKs[_ia[i]]; } } } Guid?psId = ps != null ? (Guid?)Guid.NewGuid() : null; Guid?csId = cs != null ? (Guid?)Guid.NewGuid() : null; Guid?nsId = ns != null ? (Guid?)Guid.NewGuid() : null; Guid?isId = js != null ? (Guid?)Guid.NewGuid() : null; Guid?ksId = ks != null ? (Guid?)Guid.NewGuid() : null; var subcells = _subnodes?.Map(x => x?.ToPointSetCell(storage, isTemporaryImportNode)); var subcellIds = subcells?.Map(x => x?.Id); var isLeaf = _subnodes == null; #if DEBUG if (_subnodes != null) { if (ps != null) { throw new InvalidOperationException("Invariant d98ea55b-760c-4564-8076-ce9cf7d293a0."); } for (var i = 0; i < 8; i++) { var sn = _subnodes[i]; if (sn == null) { continue; } if (sn._cell.Exponent != this._cell.Exponent - 1) { throw new InvalidOperationException("Invariant 2c33afb4-683b-4f71-9e1f-36ec4a79fba1."); } } } #endif var pointCountTreeLeafs = subcells != null ? subcells.Sum(n => n != null?n.PointCountTree : 0) : ps.Length ; var data = ImmutableDictionary <Durable.Def, object> .Empty .Add(Durable.Octree.NodeId, Guid.NewGuid()) .Add(Durable.Octree.Cell, _cell) .Add(Durable.Octree.PointCountTreeLeafs, pointCountTreeLeafs) ; if (isTemporaryImportNode) { data = data.Add(PointSetNode.TemporaryImportNode, 0); } if (psId != null) { storage.Add(psId.ToString(), ps); var bbExactLocal = new Box3f(ps); data = data .Add(Durable.Octree.PointCountCell, ps.Length) .Add(Durable.Octree.PositionsLocal3fReference, psId.Value) .Add(Durable.Octree.BoundingBoxExactLocal, bbExactLocal) ; if (isLeaf) { var bbExactGlobal = (Box3d)bbExactLocal + center; data = data .Add(Durable.Octree.BoundingBoxExactGlobal, bbExactGlobal) ; } } else { data = data .Add(Durable.Octree.PointCountCell, 0) ; } if (csId != null) { storage.Add(csId.ToString(), cs); data = data.Add(Durable.Octree.Colors4bReference, csId.Value); } if (nsId != null) { storage.Add(nsId.ToString(), ns); data = data.Add(Durable.Octree.Normals3fReference, nsId.Value); } if (isId != null) { storage.Add(isId.ToString(), js); data = data.Add(Durable.Octree.Intensities1iReference, isId.Value); } if (ksId != null) { storage.Add(ksId.ToString(), ks); data = data.Add(Durable.Octree.Classifications1bReference, ksId.Value); } if (isLeaf) // leaf { var result = new PointSetNode(data, storage, writeToStore: true); if (storage.GetPointCloudNode(result.Id) == null) { throw new InvalidOperationException("Invariant d1022027-2dbf-4b11-9b40-4829436f5789."); } return(result); } else { for (var i = 0; i < 8; i++) { var x = subcellIds[i]; if (x.HasValue) { var id = x.Value; if (storage.GetPointCloudNode(id) == null) { throw new InvalidOperationException("Invariant 01830b8b-3c0e-4a8b-a1bd-bfd1b1be1844."); } } } var bbExactGlobal = new Box3d(subcells.Where(x => x != null).Select(x => x.BoundingBoxExactGlobal)); data = data .Add(Durable.Octree.BoundingBoxExactGlobal, bbExactGlobal) .Add(Durable.Octree.SubnodesGuids, subcellIds.Map(x => x ?? Guid.Empty)) ; var result = new PointSetNode(data, storage, writeToStore: true); if (storage.GetPointCloudNode(result.Id) == null) { throw new InvalidOperationException("Invariant 7b09eccb-b6a0-4b99-be7a-eeff53b6a98b."); } return(result); } }
internal Model(AssetLoader loader) : base(loader) { Asset context = loader.Context; string name = loader.Name; BinaryReader reader = loader.Reader; FolderAsset textureArchive = null; FolderAsset bonesFolder = new FolderAsset(this, "Bones"); FolderAsset materialsFolder = new FolderAsset(this, "Materials"); FolderAsset meshesFolder = new FolderAsset(this, "Meshes"); FolderAsset vertexDeclarationsFolder = new FolderAsset(this, "Vertex declarations"); ArrayBackedList <byte> bufferData = new ArrayBackedList <byte>(); if (context != null && context.Parent is FolderAsset) { // @"/map/m##_##_##_##/m*.flver.dcx" for DS1; textures are in the @"/map/m##/" folder. if (name.StartsWith(@"map/m")) { string folderName = name.Substring(4, 3); FolderAsset maps = (FolderAsset)context.Parent.Parent; foreach (FolderAsset child in maps.Children) { if (child.Name == folderName) { textureArchive = child; break; } } } else { textureArchive = (FolderAsset)context.Parent; } } #if Marking MarkingStream markingStream = loader.StartMarking(out reader); #endif loader.ExpectMagic(Magic); char endian = (char)reader.ReadByte(); switch (endian) { case 'L': ByteOrder = ByteOrder.LittleEndian; break; case 'B': reader = loader.MakeBigEndian(); ByteOrder = ByteOrder.BigEndian; break; default: throw new Exception(); } using (reader) { // Read header. loader.Expect((byte)0); Version = (ModelVersion)reader.ReadInt32(); if (Version != ModelVersion.DarkSouls && Version != ModelVersion.DarkSouls2) { loader.AddError(loader.Position - 4, "Unknown model version " + VersionString + "; will try to load it anyway."); } int dataOffset = reader.ReadInt32(); int dataSize = reader.ReadInt32(); if (((dataOffset + dataSize + 31) & ~31) != reader.BaseStream.Length) { loader.AddError(loader.Position - 4, "Data size and offset aren't correct."); } int boneUnknownCount = reader.ReadInt32(); int materialCount = reader.ReadInt32(); int boneCount = reader.ReadInt32(); int meshCount = reader.ReadInt32(); int meshCount2 = reader.ReadInt32(); if (meshCount != meshCount2) { loader.AddError(loader.Position - 4, "Mesh count 1 and 2 aren't the same."); } Bounds = new Box3f(reader.ReadVector3f(), reader.ReadVector3f()); Unknowns.ReadInt32s(reader, 1); // Possible the non-degenerate triangle count. Seems related. int triangleCount = reader.ReadInt32(); loader.Expect(IsDS1 ? 272 : 0x10010100); loader.Expect(IsDS1 ? 0 : 0xFFFF); int partCount = reader.ReadInt32(); int vertexDeclarationCount = reader.ReadInt32(); int materialParameterCount = reader.ReadInt32(); loader.Expect(IsDS1 ? 0 : 0x1000000); loader.ExpectZeroes(4, 8); // Calculate offsets. long boneUnknownsOffset = HeaderSize; long materialsOffset = boneUnknownsOffset + boneUnknownCount * ModelBoneUnknown.DataSize; long bonesOffset = materialsOffset + materialCount * ModelMaterial.DataSize; long meshesOffset = bonesOffset + boneCount * ModelBone.DataSize; long detailLevelsOffset = meshesOffset + meshCount * ModelMesh.DataSize; long meshVerticesOffset = detailLevelsOffset + partCount * ModelDetailLevel.DataSize; long vertexDeclarationsOffset = meshVerticesOffset + meshCount * ModelMesh.DataSizeVertexHeader; long materialParametersOffset = vertexDeclarationsOffset + vertexDeclarationCount * ModelVertexDeclaration.DataSize; long postHeaderOffset = materialParametersOffset + materialParameterCount * ModelMaterialParameter.DataSize; // BoneUnknowns ExpectedOffset(loader, boneUnknownsOffset, typeof(ModelBoneUnknown).Name); for (int index = 0; index < boneUnknownCount; index++) { boneUnknowns.Add(new ModelBoneUnknown(bonesFolder, index, loader)); } // Materials ExpectedOffset(loader, materialsOffset, typeof(ModelMaterial).Name); for (int index = 0; index < materialCount; index++) { materials.Add(new ModelMaterial(materialsFolder, index, loader)); } int expectedMaterialParameterCount = materialCount > 0 ? materials[materialCount - 1].ParameterEndIndex : 0; if (expectedMaterialParameterCount != materialParameterCount) { loader.AddError(null, "Expected material parameter count {0} doesn't match actual count {1}.", expectedMaterialParameterCount, materialParameterCount); } // Bones ExpectedOffset(loader, bonesOffset, typeof(ModelBone).Name); for (int index = 0; index < boneCount; index++) { bones.Add(new ModelBone(bonesFolder, index, loader)); } // Meshes ExpectedOffset(loader, meshesOffset, typeof(ModelMesh).Name); for (int index = 0; index < meshCount; index++) { meshes.Add(new ModelMesh(meshesFolder, index, loader)); } int expectedPartCount = meshCount > 0 ? meshes[meshCount - 1].PartEndIndex : 0; if (expectedPartCount != partCount) { throw new InvalidDataException("Expected part count doesn't match actual count."); } // Detail levels ExpectedOffset(loader, detailLevelsOffset, typeof(ModelDetailLevel).Name); foreach (ModelMesh mesh in meshes) { mesh.ReadDetailLevels(loader, dataOffset, bufferData); detailLevels.AddRange(mesh.DetailLevels); } // Mesh vertices ExpectedOffset(loader, meshVerticesOffset, typeof(ModelMesh).Name + " vertex header"); foreach (ModelMesh mesh in meshes) { mesh.ReadVertexHeaders(reader, dataOffset, bufferData); } // Vertex declarations ExpectedOffset(loader, vertexDeclarationsOffset, typeof(ModelVertexDeclaration).Name); for (int index = 0; index < vertexDeclarationCount; index++) { vertexDeclarations.Add(new ModelVertexDeclaration(vertexDeclarationsFolder, index, loader)); } // Material parameters ExpectedOffset(loader, materialParametersOffset, typeof(ModelMaterialParameter).Name); foreach (ModelMaterial material in materials) { material.ReadParameters(loader, textureArchive); materialParameters.AddRange(material.Parameters); } ExpectedOffset(loader, postHeaderOffset, "Post-header"); #if Marking if (markingStream != null) { markingStream.Report(loader); } #endif // Marking #if SkippedChecks /*int vertexDataSize = 0, indexCount = 0, indexSize = 0, vertexCount = 0, expectedTriangleCount = 0, nondegenerateTriangleCount = 0; * foreach (var mesh in Meshes) { * vertexDataSize += mesh.VertexCount * mesh.VertexSize; * vertexCount += mesh.VertexCount; * foreach (var part in mesh.Parts) { * indexCount += part.Indices.Length; * indexSize += part.Indices.Length * 2; * expectedTriangleCount += part.Indices.Length - 2; * for (int index = 0; index < part.Indices.Length - 2; index++) { * if (part.Indices[index] != part.Indices[index + 1] && part.Indices[index + 1] != part.Indices[index + 2] && part.Indices[index] != part.Indices[index + 2]) * nondegenerateTriangleCount++; * } * } * } * if (Math.Abs(expectedTriangleCount - triangleCount) > partCount) * throw new InvalidDataException("Expected triangle count doesn't match the read value.");*/ #endif } Buffer = new GraphicsBuffer(bufferData.Count == 0 ? 1 : bufferData.Count); Buffer.Write(0, bufferData.Array, 0, bufferData.Count); }
public void Write(Box3f x) { Write(x.Min); Write(x.Max); }
public FluidParticlesWithConstraint(float spacing, Box3f bounds, int boundaryCount) : base(spacing) { Bounds = bounds; this.boundaryCount = boundaryCount; CreateParticles(); }