public static MeshLOD ToMesh(this ObjectPart.PrimitiveShape.Decoded shape, AssetServiceInterface assetService) { MeshLOD mesh; switch (shape.ShapeType) { case PrimitiveShapeType.Sculpt: switch (shape.SculptType & PrimitiveSculptType.TypeMask) { case PrimitiveSculptType.Mesh: var llMesh = new LLMesh(assetService[shape.SculptMap]); mesh = llMesh.GetLOD(LLMesh.LodLevel.LOD3); break; default: mesh = assetService[shape.SculptMap].SculptMeshToMesh(shape); break; } break; default: mesh = shape.ShapeToMesh(); break; } return(mesh); }
private static void ProcessMeshes(AnArray meshList, MeshInventoryItem item) { int idx = 0; foreach (IValue iv in meshList) { var newasset = new AssetData { ID = UUID.Random, Type = AssetType.Mesh, Name = item.Name + " - Mesh " + (idx + 1).ToString() }; using (var meshstream = new MemoryStream()) { Map meshData; /* add the version tag */ using (var inputstream = new MemoryStream((BinaryData)iv)) { meshData = (Map)LlsdBinary.Deserialize(inputstream); meshData["version"] = new Integer(1); LlsdBinary.Serialize(meshData, meshstream); inputstream.CopyTo(meshstream); } newasset.Data = meshstream.ToArray(); } item.Assets.Add(newasset); item.MeshMap.Add(idx, newasset.ID); var m = new LLMesh(newasset); MeshLOD lod = m.GetLOD(LLMesh.LodLevel.LOD3); if (lod.NumFaces >= 1 && lod.NumFaces <= 9) { item.MeshFaces.Add(idx, lod.NumFaces); } ++idx; } }
private PhysicsConvexShape ConvertToMesh(PrimitivePhysicsShapeType physicsShape, ObjectPart.PrimitiveShape shape) { PhysicsConvexShape convexShape = null; bool hasHullList = false; if (shape.Type == PrimitiveShapeType.Sculpt && shape.SculptType == PrimitiveSculptType.Mesh) { var m = new LLMesh(m_AssetService[shape.SculptMap]); if (physicsShape == PrimitivePhysicsShapeType.Convex) { #if DEBUG m_Log.DebugFormat("Selected convex of {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif if (m.HasConvexPhysics()) { try { #if DEBUG m_Log.DebugFormat("Using convex of {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif convexShape = m.GetConvexPhysics(false); hasHullList = convexShape.HasHullList; return(convexShape); } catch (NoSuchMeshDataException) { /* no shape */ #if DEBUG m_Log.DebugFormat("No convex in asset of {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif } catch (Exception e) { m_Log.Warn($"Failed to get convex data of {shape.SculptType} {shape.SculptMap}", e); } } #if DEBUG else { m_Log.DebugFormat("No convex shape in {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); } #endif if (convexShape == null) { #if DEBUG m_Log.DebugFormat("Using decompose to single convex for {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif MeshLOD lod = m.GetLOD(LLMesh.LodLevel.LOD3); lod.Optimize(); convexShape = DecomposeConvex(lod, true); } } else { #if DEBUG m_Log.DebugFormat("Selected detailed physics of {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif if (m.HasLOD(LLMesh.LodLevel.Physics)) { /* check for physics mesh before giving out the single hull */ #if DEBUG m_Log.DebugFormat("Using detailed physics of {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif MeshLOD lod = m.GetLOD(LLMesh.LodLevel.Physics); lod.Optimize(); convexShape = DecomposeConvex(lod); } else if (m.HasConvexPhysics()) { #if DEBUG m_Log.DebugFormat("Using convex of {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif try { convexShape = m.GetConvexPhysics(true); hasHullList = convexShape.HasHullList; } catch (NoSuchMeshDataException) { /* no shape */ #if DEBUG m_Log.DebugFormat("No suitable convex in asset of {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif } catch (Exception e) { m_Log.Warn($"Failed to get convex data of {shape.Type}/{shape.SculptType}/{shape.SculptMap}", e); } if (convexShape == null) { /* this way we keep convex hull type functional by having it only get active on PrimitivePhysicsShapeType.Prim */ #if DEBUG m_Log.DebugFormat("Using decompose to convex for {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif MeshLOD lod = m.GetLOD(LLMesh.LodLevel.LOD3); lod.Optimize(); convexShape = DecomposeConvex(lod); } } } } else { #if DEBUG m_Log.DebugFormat("Using decompose to convex for {0}/{1}/{2}", shape.Type, shape.SculptType, shape.SculptMap); #endif MeshLOD m = shape.ToMesh(m_AssetService); m.Optimize(); convexShape = DecomposeConvex(m, physicsShape == PrimitivePhysicsShapeType.Convex); } return(convexShape); }
private void GetObjectMatches(RayData ray, RayTestHitFlags flags, List <RayResult> results) { foreach (ObjectGroup grp in m_Scene.ObjectGroups) { if (grp.IsAttached) { /* ignore attachments */ continue; } /* flag checks are cheap so do those first */ if (((flags & RayTestHitFlags.NonPhantom) != 0 && !grp.IsPhantom) || ((flags & RayTestHitFlags.Phantom) != 0 && grp.IsPhantom) || ((flags & RayTestHitFlags.NonPhysical) != 0 && !grp.IsPhysics) || ((flags & RayTestHitFlags.Physical) != 0 && grp.IsPhysics)) { /* found a flag match */ } else { continue; } BoundingBox bbox; grp.GetBoundingBox(out bbox); bbox.CenterOffset = grp.GlobalPosition; bbox.Size *= grp.GlobalRotation; bbox.Size = bbox.Size.ComponentMax(-bbox.Size); double distance = IntersectBox(ray, ref bbox); if (distance < 0) { /* only process if linkset bounding box is hit */ continue; } foreach (ObjectPart part in grp.ValuesByKey1) { part.GetBoundingBox(out bbox); distance = IntersectBox(ray, ref bbox); if (distance < 0) { /* skip if not hit */ continue; } var res = new RayResult { ObjectId = grp.ID, PartId = part.ID }; /* calculate actual HitPoint and HitNormal */ ObjectPart.PrimitiveShape shape = part.Shape; MeshLOD lod = null; if (shape.Type == PrimitiveShapeType.Sculpt && shape.SculptType == PrimitiveSculptType.Mesh) { var m = new LLMesh(m_Scene.AssetService[shape.SculptMap]); foreach (LLMesh.LodLevel level in LodOrder) { if (m.HasLOD(level)) { lod = m.GetLOD(level); break; } } } else { lod = shape.ToMesh(m_Scene.AssetService); } if (lod != null) { lod.Optimize(); Vector3 normal; foreach (Triangle tri in lod.Triangles) { double dist = IntersectTri(ray, lod.Vertices[tri.Vertex1], lod.Vertices[tri.Vertex2], lod.Vertices[tri.Vertex3], out normal); if (dist >= 0) { res.HitNormalWorld = normal; res.HitPointWorld = ray.Origin + ray.Direction * dist; results.Add(res); break; } } } } } }