void UpdateMesh(MeshShape meshShape) { mesh.Clear(); mesh.vertices = meshShape.vertices; mesh.triangles = meshShape.triangles; mesh.RecalculateNormals(); }
unsafe RayCastResult GetRayCastResultFromNative(NativeRayCastResult *native) { RayCastResult result = new RayCastResult(); if (native->shape != IntPtr.Zero) { result.Shape = PhysXPhysicsWorld.Instance.GetShapeByNativePointer(native->shape); result.Position = native->worldImpact; result.Normal = native->worldNormal; result.Distance = native->distance; if (result.Shape.ShapeType == Shape.Type.Mesh) { MeshShape meshShape = (MeshShape)result.Shape; if (meshShape.MeshType != MeshShape.MeshTypes.ConvexHullDecomposition) { result.TriangleID = native->faceID; } } else if (result.Shape.ShapeType == Shape.Type.HeightField) { result.TriangleID = native->faceID; } else { result.TriangleID = 0; } } return(result); }
public static MeshShapeView CreateView(this MeshShape shape) { var view = new GameObject(shape.node.name).AddComponent <MeshShapeView>(); view.Attach(shape); return(view); }
private SceneNode BuildFingerAt(float atX, float atZ, String name) { SceneNode aFinger = new SceneNode(name); // const float fingerLength = 3f; float pivotXOffset = atX; aFinger.Xform.Pivot = new Vector3(pivotXOffset, 0, atZ); MeshShape finger = new MeshShape("cylinder"); finger.Xform.RotateInYByRadian(MathHelper.PiOver2); finger.Xform.Scale = new Vector3(0.25f * kCylinderRadiusScale, 0.25f * kCylinderRadiusScale, fingerLength * kCylinderRadiusScale); finger.Xform.Translation = new Vector3(pivotXOffset + (fingerLength / 2f), 0, atZ); finger.Color = Color.Purple; aFinger.AddShape(finger); MeshShape c1 = new MeshShape("teapot"); c1.Xform.Scale = new Vector3(0.6f); c1.Xform.Translation = new Vector3(pivotXOffset + fingerLength, 0f, atZ); c1.Color = Color.DarkSlateGray; aFinger.AddShape(c1); return(aFinger); }
public Palm(float atZ, String name) : base(name) { float useXPos = Arm.kArmLength + 1f; // add the palm circle radius to it Xform.Pivot = new Vector3(Arm.kArmLength, 0, atZ); MeshShape c1 = new MeshShape("sphere"); c1.Xform.Scale = new Vector3(Arm.kSphereScale); c1.Xform.Translation = new Vector3(useXPos, 0, atZ); c1.Color = Color.Blue; AddShape(c1); MeshShape s1 = new MeshShape("teapot"); s1.Xform.Scale = new Vector3(0.5f); s1.Xform.Translation = new Vector3(useXPos, 1.1f, atZ); s1.Color = Color.DeepPink; AddShape(s1); s1 = new MeshShape("teapot"); s1.Xform.Scale = new Vector3(0.4f); s1.Xform.Translation = new Vector3(useXPos + 1.1f, 0f, atZ); s1.Color = Color.DarkSeaGreen; AddShape(s1); AddChild(new Finger(Arm.kArmLength + 1, atZ + 1.0f, "f1")); AddChild(new Finger(Arm.kArmLength + 1, atZ - 1.0f, "f2")); }
private SceneNode BuildPalmAt(float atZ, String name) { float useXPos = kArmLength + 1f; // add the palm circle radius to it SceneNode palm = new SceneNode(name); palm.Xform.Pivot = new Vector3(kArmLength, 0, atZ); MeshShape c1 = new MeshShape("sphere"); c1.Xform.Scale = new Vector3(kSphereScale); c1.Xform.Translation = new Vector3(useXPos, 0, atZ); c1.Color = Color.Blue; palm.AddShape(c1); MeshShape s1 = new MeshShape("teapot"); s1.Xform.Scale = new Vector3(0.5f); s1.Xform.Translation = new Vector3(useXPos, 1.1f, atZ); s1.Color = Color.DeepPink; palm.AddShape(s1); s1 = new MeshShape("teapot"); s1.Xform.Scale = new Vector3(0.4f); s1.Xform.Translation = new Vector3(useXPos + 1.1f, 0f, atZ); s1.Color = Color.DarkSeaGreen; palm.AddShape(s1); SceneNode finger = BuildFingerAt(kArmLength + 1, atZ + 1.0f, "f1"); palm.AddChild(finger); finger = BuildFingerAt(kArmLength + 1, atZ - 1.0f, "f2"); palm.AddChild(finger); return(palm); }
void AddToMesh(MeshShape addMesh) { for (int i = 0; i < addMesh.triangles.Length; i++) { addMesh.triangles[i] += vertices.Length; } vertices = vertices.Concat(addMesh.vertices).ToArray(); triangles = triangles.Concat(addMesh.triangles).ToArray(); }
public void Deserialize(string[] properties) { meshShape = (MeshShape)int.Parse(properties[0]); var color = properties[1].Split(','); this.color = new Color(float.Parse(color[0]), float.Parse(color[1]), float.Parse(color[2])); // Todo: add transparency loading, transparency shaders? var emission = properties[1].Split(','); this.emission = new Color(float.Parse(emission[0]), float.Parse(emission[1]), float.Parse(emission[2])); }
public void Initialise() { _triModel = Content.Load <Model>("Models/tri"); _floorModel = Content.Load <Model>("Models/floor2"); _floorModel.EnableDefaultLighting(); _floorModel.SetDiffuseColour(Color.DarkSlateBlue); Entity.Add(new StaticBody(MeshShape.FromModel(_floorModel), (byte)HitLayers.BuildTile, Offset)); //Entity.Add(new StaticBody(MeshShape.FromModel(_triModel), (byte)HitLayers.BuildTile)); _shipRenderer = Entity.Add(new ShipSectionRenderer()); }
Shape CreateMesh(uint id, List <Vector3> uverts, List <Vector3> unormals, List <int> indices) { // Convert to TES vector arrays. Tes.Maths.Vector3[] verts = Tes.Maths.Vector3Ext.FromUnity(uverts.ToArray()); Tes.Maths.Vector3[] normals = Tes.Maths.Vector3Ext.FromUnity(unormals.ToArray()); MeshShape mesh = new MeshShape(MeshDrawType.Triangles, verts, indices.ToArray(), new Tes.Maths.Vector3((float)id)); mesh.ID = id; mesh.Normals = normals; mesh.Position = new Tes.Maths.Vector3((float)id); return(mesh); }
private void InitCameraParameters(SceneNode refNode) { mCameraPos = new MeshShape("sphere"); mAtPos = new MeshShape("sphere"); mUpPos = new MeshShape("sphere"); mCameraPos.Xform.Scale = new Vector3(kSphereScale * 0.2f); mAtPos.Xform.Scale = new Vector3(kSphereScale * 0.2f); mUpPos.Xform.Scale = new Vector3(kSphereScale * 0.2f); mCameraRefNode = refNode; mLevel1 = mCameraRefNode.GetChildren()[1]; mLevel2 = mLevel1.GetChildren()[0]; mLevel1.Xform.RotateInZByRadian(-MathHelper.Pi / 8.0f); mLevel2.Xform.RotateInZByRadian(-MathHelper.Pi / 16.0f); }
/// <summary> /// Constructor /// </summary> public MyModel() { mTheStack = new MatrixStack(); mMajorAxis = new AxisShape(); mMajorAxis.Xform.Scale = new Vector3(10, 10, 10); mRoot = new SceneNode("Root"); SceneNode arm = BuildArm("TopArm"); mRoot.AddChild(arm); arm.Xform.RotateInYByRadian(MathHelper.PiOver2); arm.Xform.Translation = new Vector3(0, 15, 20); InitCameraParameters(arm); arm = BuildArm("BottomArm"); mRoot.AddChild(arm); arm.Xform.Translation = new Vector3(0, 2, 0); SceneNode others = new SceneNode("Other Stuff"); mRoot.AddChild(others); MeshShape m = new MeshShape("cone"); m.Xform.Translation = new Vector3(-10, 3, 0); others.AddShape(m); SquareOnXZ s = new SquareOnXZ(); s.Xform.Scale = new Vector3(20, 20, 20); s.Xform.Translation = new Vector3(0, -2, 0); s.Color = Color.DarkGray; others.AddShape(s); m = new MeshShape("shusui"); m.Xform.Translation = new Vector3(8, 2, -10); m.Xform.Scale = new Vector3(4f); others.AddShape(m); m = new MeshShape("bigship1"); m.Xform.Translation = new Vector3(-5, 2, -5); m.Xform.Scale = new Vector3(0.5f, 0.5f, 0.5f); others.AddShape(m); }
private SceneNode BuildArm(String name) { SceneNode node = new SceneNode(name); MeshShape m = new MeshShape("cylinder"); m.Color = Color.Blue; node.AddShape(m); // arm and the decorations MeshShape arm = new MeshShape("cylinder"); arm.Xform.RotateInYByRadian(MathHelper.PiOver2); arm.Xform.Scale = new Vector3(kArmWidth * kCylinderRadiusScale, 0.7f, kArmLength * kCylinderLengthScale); arm.Xform.Translation = new Vector3(kArmLength / 2f, 0, 0); node.AddShape(arm); MeshShape c1 = new MeshShape("sphere"); c1.Xform.Scale = new Vector3(1.0f * kSphereScale); c1.Xform.Translation = new Vector3(kArmLength / 4f, 0f, 0); c1.Color = Color.DarkSlateBlue; node.AddShape(c1); c1 = new MeshShape("sphere"); c1.Xform.Scale = new Vector3(1.0f * kSphereScale); c1.Xform.Translation = new Vector3(kArmLength / 2f, 0f, 0); c1.Color = Color.Black; node.AddShape(c1); c1 = new MeshShape("sphere"); c1.Xform.Scale = new Vector3(1.0f * kSphereScale); c1.Xform.Translation = new Vector3(kArmLength * 0.75f, 0f, 0); c1.Color = Color.DarkSlateBlue; node.AddShape(c1); SceneNode palm = BuildPalmAt(kArmWidth / 2f, "Top"); node.AddChild(palm); palm = BuildPalmAt(0, "Mid"); node.AddChild(palm); palm = BuildPalmAt(-kArmWidth / 2f, "Bottom"); node.AddChild(palm); return(node); }
bool ValidateMeshShape(Shape shape, Shape referenceShape, MessageHandler handler) { MeshHandler meshHandler = (MeshHandler)handler; MeshHandler.MeshEntry meshEntry = meshHandler.ShapeCache.GetShapeData <MeshHandler.MeshEntry>(shape.ID); MeshShape meshShapeReference = (MeshShape)referenceShape; bool ok = true; ok = ValidateVectors("Vertex", meshEntry.Mesh.Vertices, meshShapeReference.Vertices) && ok; if (meshEntry.Mesh.HasNormals) { Vector3[] normals = meshEntry.Mesh.Normals; if (meshShapeReference.Normals.Length == 1) { // Single uniform normal will have been expanded. Extract just the first normal. normals = new Vector3[] { meshEntry.Mesh.Normals[0] }; } ok = ValidateVectors("Normal", normals, meshShapeReference.Normals) && ok; } else { if (meshShapeReference.Normals != null && meshShapeReference.Normals.Length > 0) { Debug.LogError("Missing normals."); ok = false; } } if (meshEntry.Mesh.IndexCount > 0) { ok = ValidateIndices("Index", meshEntry.Mesh.Indices, meshShapeReference.Indices) && ok; } else { if (meshShapeReference.Indices != null && meshShapeReference.Indices.Length > 0) { Debug.LogError("Missing indices."); ok = false; } } return(ok); }
public Finger(float atX, float atZ, String name) : base(name) { const float fingerLength = 3f; float pivotXOffset = atX; Xform.Pivot = new Vector3(pivotXOffset, 0, atZ); MeshShape finger = new MeshShape("cylinder"); Xform.RotateInYByRadian(MathHelper.PiOver2); Xform.Scale = new Vector3(0.25f * Arm.kCylinderRadiusScale, 0.25f * Arm.kCylinderRadiusScale, fingerLength * Arm.kCylinderRadiusScale); finger.Xform.Translation = new Vector3(pivotXOffset + (fingerLength / 2f), 0, atZ); finger.Color = Color.Purple; AddShape(finger); MeshShape c1 = new MeshShape("teapot"); c1.Xform.Scale = new Vector3(0.6f); c1.Xform.Translation = new Vector3(pivotXOffset + fingerLength, 0f, atZ); c1.Color = Color.DarkSlateGray; AddShape(c1); }
/// <summary> /// Overridden to handle triangle data in the <paramref name="msg"/> /// </summary> /// <param name="msg"></param> /// <param name="packet"></param> /// <param name="reader"></param> /// <returns></returns> protected override Error HandleMessage(DataMessage msg, PacketBuffer packet, BinaryReader reader) { ShapeCache cache = (msg.ObjectID == 0) ? _transientCache : _shapeCache; int shapeIndex = (msg.ObjectID == 0) ? _lastTransientIndex : cache.GetShapeIndex(msg.ObjectID); if (shapeIndex < 0) { return(new Error(ErrorCode.InvalidObjectID, msg.ObjectID)); } // Naive support for multiple packets. Assume: // - In order. MeshEntry meshEntry = cache.GetShapeDataByIndex <MeshEntry>(shapeIndex); // Well, this is confusing indirection... int readComponent = MeshShape.ReadDataComponentDeferred( reader, (uint)meshEntry.Mesh.VertexCount, (uint)meshEntry.Mesh.IndexCount, // Vertex handler. new MeshShape.ComponentBlockReader((MeshShape.SendDataType dataType, BinaryReader reader2, uint offset, uint count) => { return(ReadMeshVector3Data(reader2, offset, count, (Vector3[] buffer, int writeOffset, int writeCount) => { meshEntry.Mesh.SetVertices(buffer, 0, writeOffset, writeCount, true); })); }), // Index handler new MeshShape.ComponentBlockReader((MeshShape.SendDataType dataType, BinaryReader reader2, uint offset, uint count) => { return(ReadIndexComponent(reader2, offset, count, meshEntry.Mesh)); }), // Normals handler. new MeshShape.ComponentBlockReader((MeshShape.SendDataType dataType, BinaryReader reader2, uint offset, uint count) => { return(ReadMeshVector3Data(reader2, offset, count, (Vector3[] buffer, int writeOffset, int writeCount) => { if (dataType == MeshShape.SendDataType.UniformNormal) { // Only one normal for the whole mesh. // Fill the buffer and write in chunks. for (int i = 1; i < buffer.Length; ++i) { buffer[i] = buffer[0]; } int localOffset = 0; for (int i = 0; i < meshEntry.Mesh.VertexCount; i += buffer.Length) { int blockCount = Math.Min(buffer.Length, meshEntry.Mesh.VertexCount - localOffset); meshEntry.Mesh.SetNormals(buffer, 0, localOffset, blockCount); writeOffset += blockCount; } } else { meshEntry.Mesh.SetNormals(buffer, 0, writeOffset, writeCount); } })); }), // Colours handler. new MeshShape.ComponentBlockReader((MeshShape.SendDataType dataType, BinaryReader reader2, uint offset, uint count) => { return(ReadColourComponent(reader2, offset, count, meshEntry.Mesh)); }) ); if (readComponent == -1) { return(new Error(ErrorCode.MalformedMessage, DataMessage.MessageID)); } if (readComponent == (int)(MeshShape.SendDataType.Vertices | MeshShape.SendDataType.End)) { // Finalise the material. meshEntry.Material = CreateMaterial(cache.GetShapeByIndex(shapeIndex), meshEntry); cache.SetShapeDataByIndex(shapeIndex, meshEntry); } return(new Error()); }
void Start() { a = new Node("Square").AddBehavior(new MeshShape(Mesh2.square)); b = new Node("Circle").AddBehavior(new CircleShape()); b.radius = 0.5; }
void Start() { body = new Node("Shape").AddBehavior(new MeshShape(Mesh2.square)); }
private void CreateDecalForStaticObject(ShapeTriangleID startTriangle, Vec3 pos, Vec3 normal, MapObject parentMapObject) { bool existsNormalsMore45Degrees = false; //find near triangles //Set<ShapeTriangleID> triangleIDs = new Set<ShapeTriangleID>(); { Sphere checkSphere = new Sphere(pos, Type.Size * .5f * 1.41f);//Sqrt(2) //Set<ShapeTriangleID> checkedTriangles = new Set<ShapeTriangleID>(); //Stack<ShapeTriangleID> trianglesForCheck = new Stack<ShapeTriangleID>( 16 ); trianglesForCheck.Push(startTriangle); while (trianglesForCheck.Count != 0) { ShapeTriangleID triangle = trianglesForCheck.Pop(); //add to checked triangles if (!checkedTriangles.AddWithCheckAlreadyContained(triangle)) { //ignore already checked triangles continue; } //get triangle points Vec3 p0, p1, p2; { switch (triangle.shape.ShapeType) { case Shape.Type.Mesh: MeshShape meshShape = (MeshShape)triangle.shape; meshShape.GetTriangle(triangle.triangleID, true, out p0, out p1, out p2); break; case Shape.Type.HeightField: HeightFieldShape heightFieldShape = (HeightFieldShape)triangle.shape; heightFieldShape.GetTriangle(triangle.triangleID, true, out p0, out p1, out p2); break; default: Log.Fatal("DecalCreator: CreateDecalForStaticObject: Not supported shape type ({0}).", triangle.shape.ShapeType); return; } } //cull by checkBounds if (!checkSphere.TriangleIntersection(p0, p1, p2)) { continue; } //check normal bool correctNormal = false; if (Type.SpreadType != DecalCreatorType.SpreadTypes.Directional) { Plane plane = Plane.FromPoints(p0, p1, p2); if (plane.GetSide(pos + normal) == Plane.Side.Positive) { Radian angle = MathFunctions.ACos(Vec3.Dot(normal, plane.Normal)); if (angle <= new Degree(70.0f).InRadians()) { if (!existsNormalsMore45Degrees && angle >= new Degree(45.0f).InRadians()) { existsNormalsMore45Degrees = true; } correctNormal = true; } } } else { correctNormal = true; } if (correctNormal) { //add triangle to result list triangleIDs.Add(triangle); } //add near triangles to check list { //expand vertices const float border = .001f; Vec3 center = (p0 + p1 + p2) * (1.0f / 3.0f); Vec3 diff0 = p0 - center; Vec3 diff1 = p1 - center; Vec3 diff2 = p2 - center; if (diff0 != Vec3.Zero && diff1 != Vec3.Zero && diff2 != Vec3.Zero) { p0 += diff0.GetNormalize() * border; p1 += diff1.GetNormalize() * border; p2 += diff2.GetNormalize() * border; Vec3 p01 = (p0 + p1) * .5f; Vec3 p12 = (p1 + p2) * .5f; Vec3 p20 = (p2 + p0) * .5f; //find triangles for (int n = 0; n < 3; n++) { Vec3 p = Vec3.Zero; switch (n) { case 0: p = p01; break; case 1: p = p12; break; case 2: p = p20; break; } RayCastResult[] piercingResult = PhysicsWorld.Instance.RayCastPiercing(new Ray( p + normal * .025f, -normal * .05f), (int)ContactGroup.CastOnlyCollision); foreach (RayCastResult result in piercingResult) { if (result.Shape != null) { trianglesForCheck.Push(new ShapeTriangleID( result.Shape, result.TriangleID)); } } } } } } checkedTriangles.Clear(); } if (triangleIDs.Count == 0) { return; } //calculate perpendiculars to normal Vec3 side1Normal; Vec3 side2Normal; { if (Math.Abs(normal.X) > .001f || Math.Abs(normal.Y) > .001f) { side1Normal = Mat3.FromRotateByZ(MathFunctions.PI / 2) * new Vec3(normal.X, normal.Y, 0); side1Normal.Normalize(); } else { side1Normal = new Vec3(1, 0, 0); } side2Normal = Vec3.Cross(normal, side1Normal); } //generate clip planes Plane[] clipPlanes = new Plane[6]; { float halfSize = Type.Size * .5f; if (existsNormalsMore45Degrees) { halfSize *= 1.41f; } Plane p; p = Plane.FromVectors(normal, -side2Normal, Position); clipPlanes[0] = new Plane(p.Normal, p.Distance + halfSize); p = Plane.FromVectors(normal, side2Normal, Position); clipPlanes[1] = new Plane(p.Normal, p.Distance + halfSize); p = Plane.FromVectors(normal, -side1Normal, Position); clipPlanes[2] = new Plane(p.Normal, p.Distance + halfSize); p = Plane.FromVectors(normal, side1Normal, Position); clipPlanes[3] = new Plane(p.Normal, p.Distance + halfSize); p = Plane.FromVectors(side1Normal, side2Normal, Position); clipPlanes[4] = new Plane(p.Normal, p.Distance + halfSize); //clipPlanes[ 4 ] = new Plane( p.Normal, p.Distance + halfSize * .5f ); p = Plane.FromVectors(side1Normal, -side2Normal, Position); clipPlanes[5] = new Plane(p.Normal, p.Distance + halfSize); //clipPlanes[ 5 ] = new Plane( p.Normal, p.Distance + halfSize * .5f ); } //generate vertices and indices by triangles //List<Decal.Vertex> vertices = new List<Decal.Vertex>( triangleIDs.Count * 3 ); //List<int> indices = new List<int>( triangleIDs.Count * 3 ); List <Decal.Vertex> vertices = tempVertices; List <int> indices = tempIndices; vertices.Clear(); indices.Clear(); { foreach (ShapeTriangleID triangle in triangleIDs) { Vec3 p0, p1, p2; { switch (triangle.shape.ShapeType) { case Shape.Type.Mesh: MeshShape meshShape = (MeshShape)triangle.shape; meshShape.GetTriangle(triangle.triangleID, true, out p0, out p1, out p2); break; case Shape.Type.HeightField: HeightFieldShape heightFieldShape = (HeightFieldShape)triangle.shape; heightFieldShape.GetTriangle(triangle.triangleID, true, out p0, out p1, out p2); break; default: Log.Fatal("DecalCreator: CreateDecalForStaticObject: Not supported shape type ({0}).", triangle.shape.ShapeType); return; } } List <Vec3> list = new List <Vec3>(); list.Add(p0); list.Add(p1); list.Add(p2); //clip by planes foreach (Plane plane in clipPlanes) { list = CutConvexPlanePolygonByPlane(list, plane); if (list == null) { break; } } //add to vertices and indices lists if (list != null) { int vertexCount = vertices.Count; Vec3 norm = Plane.FromPoints(p0, p1, p2).Normal; foreach (Vec3 p in list) { vertices.Add(new Decal.Vertex(p, norm, Vec2.Zero, Vec3.Zero)); } for (int n = 1; n < list.Count - 1; n++) { indices.Add(vertexCount); indices.Add(vertexCount + n); indices.Add(vertexCount + n + 1); } } } } triangleIDs.Clear(); if (indices.Count == 0) { return; } //calculate texCoord and Type.DepthRenderOffset { Plane planeSide1 = Plane.FromVectors(normal, side1Normal, Position); Plane planeSide2 = Plane.FromVectors(normal, side2Normal, Position); float invSize = 1.0f / Type.Size; for (int n = 0; n < vertices.Count; n++) { Decal.Vertex vertex = vertices[n]; //calculate texCoord float distance1 = planeSide1.GetDistance(vertex.position); float distance2 = planeSide2.GetDistance(vertex.position); vertex.texCoord = new Vec2(distance1 * invSize + .5f, distance2 * invSize + .5f); //Add perpendicular to normal offset. //Alternative way: for shader based rendering use DepthOffset property of decal material. //if( !RenderSystem.Instance.HasShaderModel3() ) { //add Type.DepthRenderOffset vertex.position = vertex.position + normal * Type.DepthRenderOffset; } vertices[n] = vertex; } } //calculate tangent vectors { int triangleCount = indices.Count / 3; for (int nTriangle = 0; nTriangle < triangleCount; nTriangle++) { int index0 = indices[nTriangle * 3 + 0]; int index1 = indices[nTriangle * 3 + 1]; int index2 = indices[nTriangle * 3 + 2]; Decal.Vertex vertex0 = vertices[index0]; Decal.Vertex vertex1 = vertices[index1]; Decal.Vertex vertex2 = vertices[index2]; Vec3 tangent = MathUtils.CalculateTangentSpaceVector( vertex0.position, vertex0.texCoord, vertex1.position, vertex1.texCoord, vertex2.position, vertex2.texCoord); vertex0.tangent += tangent; vertex1.tangent += tangent; vertex2.tangent += tangent; vertices[index0] = vertex0; vertices[index1] = vertex1; vertices[index2] = vertex2; } for (int n = 0; n < vertices.Count; n++) { Decal.Vertex vertex = vertices[n]; if (vertex.tangent != Vec3.Zero) { vertex.tangent.Normalize(); } vertices[n] = vertex; } } //subtract decal position (make local vertices coordinates) { for (int n = 0; n < vertices.Count; n++) { Decal.Vertex vertex = vertices[n]; vertex.position -= Position; vertices[n] = vertex; } } //get material string materialName = null; { string physicsMaterialName = startTriangle.shape.MaterialName; string defaultMaterialName = ""; foreach (DecalCreatorType.MaterialItem item in Type.Materials) { if (item.PhysicsMaterialName == physicsMaterialName) { materialName = item.MaterialName; } if (string.IsNullOrEmpty(item.PhysicsMaterialName)) { defaultMaterialName = item.MaterialName; } } if (materialName == null) { materialName = defaultMaterialName; } } //create Decal Decal decal = (Decal)Entities.Instance.Create("Decal", Map.Instance); decal.Position = Position; decal.Init(this, vertices.ToArray(), indices.ToArray(), materialName, parentMapObject); decal.PostCreate(); Type.AddDecalToCreatedList(decal); decals.Add(decal); }
private void buttonExport_Click(object sender, EventArgs e) { lastOutputMapName = textBoxOutputFileName.Text; string fileName = textBoxOutputFileName.Text.Trim(); bool rooted; try { rooted = Path.IsPathRooted(fileName); } catch { rooted = false; } if (!rooted) { Log.Warning(Translate("Invalid file name.")); return; } string caption = Translate("Export To 3D Model Add-on"); if (File.Exists(fileName)) { string template = Translate("The file with the name \"{0}\" is already exists. Overwrite?"); string text = string.Format(template, fileName); if (MessageBox.Show(text, caption, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK) { return; } } try { using (new CursorKeeper(Cursors.WaitCursor)) { //get selected entities List <Entity> selectedEntities; if (checkBoxExportSelectedObjectsOnly.Checked) { selectedEntities = MapEditorInterface.Instance.GetSelectedEntities(); } else { selectedEntities = new List <Entity>(); } Set <Entity> selectedEntitiesSet = new Set <Entity>(); foreach (Entity entity in selectedEntities) { selectedEntitiesSet.AddWithCheckAlreadyContained(entity); } string extension = Path.GetExtension(fileName); ModelImportLoader loader = MeshManager.Instance.GetModeImportLoaderByExtension(extension); if (loader == null) { Log.Warning(Translate("File extension \"{0}\" is not supported."), extension); return; } List <ModelImportLoader.SaveGeometryItem> geometry = new List <ModelImportLoader.SaveGeometryItem>(); Set <string> names = new Set <string>(); //SceneNodes foreach (SceneNode sceneNode in SceneManager.Instance.SceneNodes) { Entity entity = sceneNode._InternalUserData as Entity; if (entity != null) { if (selectedEntities.Count == 0 || selectedEntitiesSet.Contains(entity)) { foreach (MovableObject movableObject in sceneNode.MovableObjects) { MeshObject meshObject = movableObject as MeshObject; if (meshObject != null) { foreach (SubMesh subMesh in meshObject.Mesh.SubMeshes) { string uniqueName = GetUniqueName(names, entity); VertexData vertexData = subMesh.UseSharedVertices ? subMesh.Parent.SharedVertexData : subMesh.VertexData; IndexData indexData = subMesh.IndexData; ModelImportLoader.SaveGeometryItem item = new ModelImportLoader.SaveGeometryItem( vertexData, indexData, sceneNode.Position, sceneNode.Rotation, sceneNode.Scale, uniqueName); geometry.Add(item); names.Add(uniqueName); } } } } } } foreach (Entity entity in Map.Instance.Children) { if (selectedEntities.Count == 0 || selectedEntitiesSet.Contains(entity)) { //StaticMesh StaticMesh staticMesh = entity as StaticMesh; if (staticMesh != null) { Mesh mesh = MeshManager.Instance.Load(staticMesh.MeshName); if (mesh != null) { foreach (SubMesh subMesh in mesh.SubMeshes) { string uniqueName = GetUniqueName(names, entity); VertexData vertexData = subMesh.UseSharedVertices ? subMesh.Parent.SharedVertexData : subMesh.VertexData; IndexData indexData = subMesh.IndexData; ModelImportLoader.SaveGeometryItem item = new ModelImportLoader.SaveGeometryItem(vertexData, indexData, staticMesh.Position, staticMesh.Rotation, staticMesh.Scale, uniqueName); geometry.Add(item); names.Add(uniqueName); } } } //HeightmapTerrain if (entity.Type.Name == "HeightmapTerrain") { try { MethodInfo method = entity.GetType().GetMethod("GetBodies"); Body[] bodies = (Body[])method.Invoke(entity, new object[0]); foreach (Body body in bodies) { foreach (Shape shape in body.Shapes) { //MeshShape MeshShape meshShape = shape as MeshShape; if (meshShape != null) { Vec3[] vertices; int[] indices; if (meshShape.GetData(out vertices, out indices)) { ModelImportLoader.SaveGeometryItem.Vertex[] vertices2 = new ModelImportLoader.SaveGeometryItem.Vertex[vertices.Length]; for (int n = 0; n < vertices.Length; n++) { vertices2[n] = new ModelImportLoader.SaveGeometryItem.Vertex(vertices[n]); } string uniqueName = GetUniqueName(names, entity); ModelImportLoader.SaveGeometryItem item = new ModelImportLoader.SaveGeometryItem(vertices2, indices, false, body.Position, body.Rotation, new Vec3(1, 1, 1), uniqueName); if (item != null) { geometry.Add(item); names.Add(uniqueName); } } } //HeightFieldShape HeightFieldShape heightFieldShape = shape as HeightFieldShape; if (heightFieldShape != null) { Vec3[] vertices; int[] indices; heightFieldShape.GetVerticesAndIndices(false, false, out vertices, out indices); ModelImportLoader.SaveGeometryItem.Vertex[] vertices2 = new ModelImportLoader.SaveGeometryItem.Vertex[vertices.Length]; for (int n = 0; n < vertices.Length; n++) { vertices2[n] = new ModelImportLoader.SaveGeometryItem.Vertex(vertices[n]); } string uniqueName = GetUniqueName(names, entity); ModelImportLoader.SaveGeometryItem item = new ModelImportLoader.SaveGeometryItem(vertices2, indices, false, body.Position, body.Rotation, new Vec3(1, 1, 1), uniqueName); if (item != null) { geometry.Add(item); names.Add(uniqueName); } } } } } catch { } } } } ////StaticMeshObjects //foreach( StaticMeshObject staticMeshObject in SceneManager.Instance.StaticMeshObjects ) //{ // Entity entity = staticMeshObject._InternalUserData as Entity; // if( entity != null ) // { // if( selectedEntities.Count == 0 || selectedEntitiesSet.Contains( entity ) ) // { // string name = entity.Name; // if( string.IsNullOrEmpty( name ) ) // name = entity.ToString(); // string uniqueName; // for( int n = 1; ; n++ ) // { // uniqueName = name; // if( n != 1 ) // uniqueName += n.ToString(); // if( !names.Contains( uniqueName ) ) // break; // } // ModelImportLoader.SaveGeometryItem item = new ModelImportLoader.SaveGeometryItem( // staticMeshObject.VertexData, staticMeshObject.IndexData, staticMeshObject.Position, // staticMeshObject.Rotation, staticMeshObject.Scale, uniqueName ); // geometry.Add( item ); // names.Add( uniqueName ); // } // } //} if (geometry.Count == 0) { Log.Warning(Translate("No data to export.")); return; } if (!loader.Save(geometry, fileName)) { return; } } } catch (Exception ex) { Log.Warning(Translate("Error.") + "\n\n" + ex.Message); return; } MessageBox.Show(Translate("The geometry successfully exported!"), caption); }
unsafe void CreateTriangleMeshShape( MeshShape shape, IntPtr pxTriangleMesh, float totalVolume ) { //if( shape.PerTriangleMaterials != null && shape.PerTriangleMaterials.Length > 127 ) // Log.Fatal( "PhysXBody: CreateTriangleMeshShape: The amount of per triangle materials can't be more than 127." ); Vec3 position = shape.Position; Quat rotation = shape.Rotation; float mass = GetShapeMass( shape, totalVolume ); IntPtr[] materials; if( shape.PerTriangleMaterials != null && shape.PerTriangleMaterials.Length > 0 ) { materials = new IntPtr[ shape.PerTriangleMaterials.Length ]; for( int n = 0; n < materials.Length; n++ ) { MeshShape.PerTriangleMaterial item = shape.PerTriangleMaterials[ n ]; materials[ n ] = PhysXNativeMaterial.Create( item.StaticFriction, item.DynamicFriction, item.Restitution, item.MaterialName, item.VehicleDrivableSurface ); } } else materials = new IntPtr[] { CreateMaterial( shape ) }; //IntPtr material = CreateMaterial( shape ); fixed( IntPtr* pMaterials = materials ) { PhysXNativeBody.CreateTriangleMeshShape( nativeBody, ref position, ref rotation, pxTriangleMesh, materials.Length, pMaterials, mass, shape.ContactGroup ); } }
void Start() { a = new Node("A").AddBehavior(new MeshShape(Mesh2.square)); b = new Node("B").AddBehavior(new MeshShape(Mesh2.square)); }
public void Attach(MeshShape shape, Color color) { Attach(shape); renderer.material.color = color; }
private unsafe void UpdateGeometry() { DestroyGeometry(); Curve positionCurve = GetPositionCurve(); Curve radiusCurve = null; { bool existsSpecialRadius = false; foreach (MapCurvePoint point in Points) { RenderableCurvePoint point2 = point as RenderableCurvePoint; if (point2 != null && point2.OverrideRadius >= 0) { existsSpecialRadius = true; break; } } if (existsSpecialRadius) { switch (radiusCurveType) { case RadiusCurveTypes.UniformCubicSpline: radiusCurve = new UniformCubicSpline(); break; case RadiusCurveTypes.Bezier: radiusCurve = new BezierCurve(); break; case RadiusCurveTypes.Line: radiusCurve = new LineCurve(); break; } for (int n = 0; n < Points.Count; n++) { MapCurvePoint point = Points[n]; if (!point.Editor_IsExcludedFromWorld()) { float rad = radius; RenderableCurvePoint renderableCurvePoint = point as RenderableCurvePoint; if (renderableCurvePoint != null && renderableCurvePoint.OverrideRadius >= 0) { rad = renderableCurvePoint.OverrideRadius; } radiusCurve.AddValue(point.Time, new Vec3(rad, 0, 0)); } } } } //create mesh Vertex[] vertices = null; int[] indices = null; if (positionCurve != null && positionCurve.Values.Count > 1 && Points.Count >= 2) { Vec3 positionOffset = -Position; int steps = (Points.Count - 1) * pathSteps + 1; int vertexCount = steps * (shapeSegments + 1); int indexCount = (steps - 1) * shapeSegments * 2 * 3; vertices = new Vertex[vertexCount]; indices = new int[indexCount]; //fill data { int currentVertex = 0; int currentIndex = 0; float currentDistance = 0; Vec3 lastPosition = Vec3.Zero; Quat lastRot = Quat.Identity; for (int nStep = 0; nStep < steps; nStep++) { int startStepVertexIndex = currentVertex; float coefficient = (float)nStep / (float)(steps - 1); Vec3 pos = CalculateCurvePointByCoefficient(coefficient) + positionOffset; Quat rot; { Vec3 v = CalculateCurvePointByCoefficient(coefficient + .3f / (float)(steps - 1)) - CalculateCurvePointByCoefficient(coefficient); if (v != Vec3.Zero) { rot = Quat.FromDirectionZAxisUp(v.GetNormalize()); } else { rot = lastRot; } } if (nStep != 0) { currentDistance += (pos - lastPosition).Length(); } float rad; if (radiusCurve != null) { Range range = new Range(radiusCurve.Times[0], radiusCurve.Times[radiusCurve.Times.Count - 1]); float t = range.Minimum + (range.Maximum - range.Minimum) * coefficient; rad = radiusCurve.CalculateValueByTime(t).X; } else { rad = radius; } for (int nSegment = 0; nSegment < shapeSegments + 1; nSegment++) { float rotateCoefficient = ((float)nSegment / (float)(shapeSegments)); float angle = rotateCoefficient * MathFunctions.PI * 2; Vec3 p = pos + rot * new Vec3(0, MathFunctions.Cos(angle) * rad, MathFunctions.Sin(angle) * rad); Vertex vertex = new Vertex(); vertex.position = p; Vec3 pp = p - pos; if (pp != Vec3.Zero) { vertex.normal = pp.GetNormalize(); } else { vertex.normal = Vec3.XAxis; } //vertex.normal = ( p - pos ).GetNormalize(); vertex.texCoord = new Vec2(currentDistance * textureCoordinatesTilesPerMeter, rotateCoefficient + .25f); vertex.tangent = new Vec4(rot.GetForward(), 1); vertices[currentVertex++] = vertex; } if (nStep < steps - 1) { for (int nSegment = 0; nSegment < shapeSegments; nSegment++) { indices[currentIndex++] = startStepVertexIndex + nSegment; indices[currentIndex++] = startStepVertexIndex + nSegment + 1; indices[currentIndex++] = startStepVertexIndex + nSegment + 1 + shapeSegments + 1; indices[currentIndex++] = startStepVertexIndex + nSegment + 1 + shapeSegments + 1; indices[currentIndex++] = startStepVertexIndex + nSegment + shapeSegments + 1; indices[currentIndex++] = startStepVertexIndex + nSegment; } } lastPosition = pos; lastRot = rot; } if (currentVertex != vertexCount) { Log.Fatal("RenderableCurve: UpdateRenderingGeometry: currentVertex != vertexCount."); } if (currentIndex != indexCount) { Log.Fatal("RenderableCurve: UpdateRenderingGeometry: currentIndex != indexCount."); } } if (vertices.Length != 0 && indices.Length != 0) { //create mesh string meshName = MeshManager.Instance.GetUniqueName( string.Format("__RenderableCurve_{0}_{1}", Name, uniqueMeshIdentifier)); uniqueMeshIdentifier++; //string meshName = MeshManager.Instance.GetUniqueName( string.Format( "__RenderableCurve_{0}", Name ) ); mesh = MeshManager.Instance.CreateManual(meshName); SubMesh subMesh = mesh.CreateSubMesh(); subMesh.UseSharedVertices = false; //init vertexData VertexDeclaration declaration = subMesh.VertexData.VertexDeclaration; declaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position); declaration.AddElement(0, 12, VertexElementType.Float3, VertexElementSemantic.Normal); declaration.AddElement(0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0); declaration.AddElement(0, 32, VertexElementType.Float4, VertexElementSemantic.Tangent, 0); fixed(Vertex *pVertices = vertices) { subMesh.VertexData = VertexData.CreateFromArray(declaration, (IntPtr)pVertices, vertices.Length * Marshal.SizeOf(typeof(Vertex))); } subMesh.IndexData = IndexData.CreateFromArray(indices, 0, indices.Length, false); //set material subMesh.MaterialName = materialName; //set mesh gabarites Bounds bounds = Bounds.Cleared; foreach (Vertex vertex in vertices) { bounds.Add(vertex.position); } mesh.SetBoundsAndRadius(bounds, bounds.GetRadius()); } } //create MeshObject, SceneNode if (mesh != null) { meshObject = SceneManager.Instance.CreateMeshObject(mesh.Name); if (meshObject != null) { meshObject.SetMaterialNameForAllSubObjects(materialName); meshObject.CastShadows = true; sceneNode = new SceneNode(); sceneNode.Attach(meshObject); //apply offset sceneNode.Position = Position; MapObject.AssociateSceneNodeWithMapObject(sceneNode, this); } } //create collision body if (mesh != null && collision) { Vec3[] positions = new Vec3[vertices.Length]; for (int n = 0; n < vertices.Length; n++) { positions[n] = vertices[n].position; } string meshPhysicsMeshName = PhysicsWorld.Instance.AddCustomMeshGeometry(positions, indices, null, MeshShape.MeshTypes.TriangleMesh, 0, 0); collisionBody = PhysicsWorld.Instance.CreateBody(); collisionBody.Static = true; collisionBody._InternalUserData = this; collisionBody.Position = Position; MeshShape shape = collisionBody.CreateMeshShape(); shape.MeshName = meshPhysicsMeshName; shape.MaterialName = CollisionMaterialName; shape.ContactGroup = (int)ContactGroup.Collision; //shape.VehicleDrivableSurface = collisionVehicleDrivableSurface; collisionBody.PushedToWorld = true; } needUpdate = false; }
public void Attach(MeshShape shape) { this.shape = shape; filter.mesh = shape.source.ToUnity(); renderer.material = material; }
public static void ValidateShape(MeshShape shape, MeshShape reference, Dictionary <ulong, Resource> resources) { ValidateShape((Shape)shape, (Shape)reference, resources); Assert.Equal(reference.DrawType, shape.DrawType); if (reference.Vertices != null) { Assert.NotNull(shape.Vertices); Assert.Equal(reference.Vertices.Length, shape.Vertices.Length); } if (reference.Normals != null) { Assert.NotNull(shape.Normals); Assert.Equal(reference.Normals.Length, shape.Normals.Length); } if (reference.Colours != null) { Assert.NotNull(shape.Colours); Assert.Equal(reference.Colours.Length, shape.Colours.Length); } if (reference.Indices != null) { Assert.NotNull(shape.Indices); Assert.Equal(reference.Indices.Length, shape.Indices.Length); } if (reference.Vertices != null) { for (int i = 0; i < reference.Vertices.Length; ++i) { Assert.Equal(reference.Vertices[i], shape.Vertices[i]); } } if (reference.Normals != null) { for (int i = 0; i < reference.Normals.Length; ++i) { Assert.Equal(reference.Normals[i], shape.Normals[i]); } } if (reference.Colours != null) { for (int i = 0; i < reference.Colours.Length; ++i) { Assert.Equal(reference.Colours[i], shape.Colours[i]); } } if (reference.Indices != null) { for (int i = 0; i < reference.Indices.Length; ++i) { Assert.Equal(reference.Indices[i], shape.Indices[i]); } } }
void CreateGeomDatas() { tempGeomDatasAsList.Clear(); for (int n = 0; n < Shapes.Length; n++) { tempGeomDatasAsList.Add(null); } dSpaceID bodySpaceID = scene.rootSpaceID; for (int nShape = 0; nShape < Shapes.Length; nShape++) { Shape shape = Shapes[nShape]; GeomData geomData = new GeomData(); geomData.shape = shape; geomData.odeBody = (ODEBody)shape.Body; bool identityTransform = shape.Position == Vec3.Zero && shape.Rotation == Quat.Identity; // No offset transform. if (identityTransform) { geomData.spaceID = bodySpaceID; } //create geom switch (shape.ShapeType) { case Shape.Type.Box: { BoxShape boxShape = (BoxShape)shape; geomData.geomID = Ode.dCreateBox(geomData.spaceID, boxShape.Dimensions.X, boxShape.Dimensions.Y, boxShape.Dimensions.Z); } break; case Shape.Type.Sphere: { SphereShape sphereShape = (SphereShape)shape; geomData.geomID = Ode.dCreateSphere(geomData.spaceID, sphereShape.Radius); } break; case Shape.Type.Capsule: { CapsuleShape capsuleShape = (CapsuleShape)shape; geomData.geomID = Ode.dCreateCapsule(geomData.spaceID, capsuleShape.Radius, capsuleShape.Length); } break; case Shape.Type.Cylinder: { CylinderShape cylinderShape = (CylinderShape)shape; geomData.geomID = Ode.dCreateCylinder(geomData.spaceID, cylinderShape.Radius, cylinderShape.Length); } break; case Shape.Type.Mesh: { MeshShape meshShape = (MeshShape)shape; if (!Static) { if (!notSupportedMeshesLogInformed) { notSupportedMeshesLogInformed = true; Log.Warning("ODEBody: Dynamic convex and triangle meshes are not " + "supported by ODE."); } Log.Info("ODEBody: Dynamic convex and triangle meshes are not " + "supported by ODE."); //ignore shape continue; } //get mesh geometry from cache PhysicsWorld._MeshGeometry geometry = meshShape._GetMeshGeometry(); //ignore shape if (geometry == null) { Log.Info("ODEBody: Mesh is not initialized. ({0}).", meshShape.MeshName); continue; } ODEPhysicsWorld.MeshGeometryODEData data; if (geometry.UserData == null) { data = new ODEPhysicsWorld.MeshGeometryODEData(); //generate MeshGeometryODEData data data.triMeshDataID = Ode.dGeomTriMeshDataCreate(); data.verticesCount = geometry.Vertices.Length; data.indicesCount = geometry.Indices.Length; data.vertices = (IntPtr)Ode.dAlloc((uint) (Marshal.SizeOf(typeof(float)) * 3 * data.verticesCount)); data.indices = (IntPtr)Ode.dAlloc((uint) (Marshal.SizeOf(typeof(int)) * data.indicesCount)); unsafe { fixed(Vec3 *source = geometry.Vertices) { NativeUtils.CopyMemory(data.vertices, (IntPtr)source, data.verticesCount * sizeof(Vec3)); } fixed(int *source = geometry.Indices) { NativeUtils.CopyMemory(data.indices, (IntPtr)source, data.indicesCount * sizeof(int)); } } //build ode tri mesh data Ode.dGeomTriMeshDataBuildSingleAsIntPtr( data.triMeshDataID, data.vertices, Marshal.SizeOf(typeof(float)) * 3, data.verticesCount, data.indices, data.indicesCount, Marshal.SizeOf(typeof(int)) * 3); geometry.UserData = data; } else { data = (ODEPhysicsWorld.MeshGeometryODEData)geometry.UserData; } data.checkRefCounter++; geomData.meshGeometryODEData = data; geomData.geomID = Ode.dCreateTriMesh(geomData.spaceID, data.triMeshDataID, null, null, null); Ode.SetGeomTriMeshSetRayCallback(geomData.geomID); //unsafe //{ // float[] planes = new float[] // { // 1.0f ,0.0f ,0.0f ,0.25f, // 0.0f ,1.0f ,0.0f ,0.25f, // 0.0f ,0.0f ,1.0f ,0.25f, // -1.0f,0.0f ,0.0f ,0.25f, // 0.0f ,-1.0f,0.0f ,0.25f, // 0.0f ,0.0f ,-1.0f,0.25f // }; // float[] points = new float[] // { // 0.25f,0.25f,0.25f, // -0.25f,0.25f,0.25f, // 0.25f,-0.25f,0.25f, // -0.25f,-0.25f,0.25f, // 0.25f,0.25f,-0.25f, // -0.25f,0.25f,-0.25f, // 0.25f,-0.25f,-0.25f, // -0.25f,-0.25f,-0.25f, // }; // uint[] polygons = new uint[] // { // 4,0,2,6,4, // 4,1,0,4,5, // 4,0,1,3,2, // 4,3,1,5,7, // 4,2,3,7,6, // 4,5,4,6,7, // }; // float* nativePlanes = (float*)Ode.dAlloc( (uint)( sizeof( float ) * planes.Length ) ); // for( int n = 0; n < planes.Length; n++ ) // nativePlanes[ n ] = planes[ n ]; // uint planeCount = 6; // float* nativePoints = (float*)Ode.dAlloc( (uint)( sizeof( float ) * points.Length ) ); // for( int n = 0; n < points.Length; n++ ) // nativePoints[ n ] = points[ n ]; // uint pointCount = 8; // uint* nativePolygons = (uint*)Ode.dAlloc( (uint)( sizeof( uint ) * polygons.Length ) ); // for( int n = 0; n < polygons.Length; n++ ) // nativePolygons[ n ] = polygons[ n ]; // //ODEPhysicsWorld.MeshGeometryODEData data; // //if( geometry.UserData == null ) // //{ // // data = new ODEPhysicsWorld.MeshGeometryODEData(); // //} // geomData.geomID = Ode.dCreateConvex( geomData.spaceID, nativePlanes, // planeCount, nativePoints, pointCount, nativePolygons ); //} } break; } //add geom data to list tempGeomDatasAsList[nShape] = geomData; geomData.shape = shape; geomData.odeBody = (ODEBody)shape.Body; // Use ODE's geom transform object. if (!identityTransform) { geomData.transformID = Ode.dCreateGeomTransform(bodySpaceID); } //set geom to body if (!Static) { if (geomData.transformID == dGeomID.Zero) { Ode.dGeomSetBody(geomData.geomID, bodyID); } else { Ode.dGeomSetBody(geomData.transformID, bodyID); } } if (geomData.transformID != dGeomID.Zero) { // Setup geom transform. Ode.dGeomTransformSetGeom(geomData.transformID, geomData.geomID); Ode.dQuaternion odeQuat; Convert.ToODE(shape.Rotation, out odeQuat); Ode.dGeomSetQuaternion(geomData.geomID, ref odeQuat); Ode.dGeomSetPosition(geomData.geomID, shape.Position.X, shape.Position.Y, shape.Position.Z); } // Set the GeomData reference for later use (e.g. in collision handling). geomData.shapeDictionaryIndex = scene.shapesDictionary.Add(geomData); dGeomID geomID = geomData.transformID != dGeomID.Zero ? geomData.transformID : geomData.geomID; Ode.CreateShapeData(geomID, bodyData, geomData.shapeDictionaryIndex, shape.ShapeType == Shape.Type.Mesh, shape.ContactGroup, shape.Hardness, shape.Restitution, shape.DynamicFriction, shape.StaticFriction); //shape pair flags Dictionary <Shape, ShapePairFlags> list = shape._GetShapePairFlags(); if (list != null) { foreach (KeyValuePair <Shape, ShapePairFlags> pair in list) { Shape otherShape = pair.Key; ShapePairFlags flags = pair.Value; if ((flags & ShapePairFlags.DisableContacts) != 0) { ODEBody otherBody = (ODEBody)otherShape.Body; GeomData otherGeomData = otherBody.GetGeomDataByShape(otherShape); if (otherGeomData != null) { dGeomID otherGeomID = (otherGeomData.transformID != dGeomID.Zero) ? otherGeomData.transformID : otherGeomData.geomID; Ode.SetShapePairDisableContacts(geomID, otherGeomID, true); } } } } } geomDatas = tempGeomDatasAsList.ToArray(); tempGeomDatasAsList.Clear(); if (Static) { UpdateStaticBodyGeomsTransform(); } }
/// <summary> /// Overridden to handle triangle data in the <paramref name="msg"/> /// </summary> /// <param name="msg"></param> /// <param name="packet"></param> /// <param name="reader"></param> /// <returns></returns> protected override Error HandleMessage(DataMessage msg, PacketBuffer packet, BinaryReader reader) { GameObject obj = null; if (msg.ObjectID == 0) { // Transient object. obj = _transientCache.LastObject; if (!obj) { return(new Error(ErrorCode.InvalidObjectID, 0)); } } else { obj = FindObject(msg.ObjectID); if (!obj) { // Object already exists. return(new Error(ErrorCode.InvalidObjectID, msg.ObjectID)); } } // Naive support for multiple packets. Assume: // - In order. // - Under the overall Unity mesh indexing limit. MeshDataComponent meshData = obj.GetComponent <MeshDataComponent>(); Vector3ComponentAdaptor normalsAdaptor = new Vector3ComponentAdaptor(meshData.Normals); ColoursAdaptor coloursAdaptor = new ColoursAdaptor(meshData.Colours); int readComponent = MeshShape.ReadDataComponent(reader, new Vector3ComponentAdaptor(meshData.Vertices), new MeshShape.ArrayComponentAdaptor <int>(meshData.Indices), normalsAdaptor, coloursAdaptor ); if (readComponent == -1) { return(new Error(ErrorCode.MalformedMessage, DataMessage.MessageID)); } // Normals and colours may have been (re)allocated. Store the results. switch (readComponent & ~(int)(MeshShape.SendDataType.End | MeshShape.SendDataType.ExpectEnd)) { case (int)MeshShape.SendDataType.Normals: case (int)MeshShape.SendDataType.UniformNormal: // Normals array may have been (re)allocated. meshData.Normals = normalsAdaptor.Array; break; case (int)MeshShape.SendDataType.Colours: // Colours array may have been (re)allocated. meshData.Colours = coloursAdaptor.Array; break; } // Check for finalisation. if ((readComponent & (int)MeshShape.SendDataType.End) != 0) { _awaitingFinalisation.Add(meshData); } return(new Error()); }
public void CollationTest(bool compress) { // Allocate encoder. CollatedPacketEncoder encoder = new CollatedPacketEncoder(compress); // Create a mesh object to generate some messages. List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <int> indices = new List <int>(); Common.MakeLowResSphere(vertices, indices, normals); MeshShape mesh = new MeshShape(Net.MeshDrawType.Triangles, vertices.ToArray(), indices.ToArray()); mesh.ID = 42; mesh.Normals = normals.ToArray(); // Use the encoder as a connection. // The Create() call will pack the mesh create message and multiple data messages. int wroteBytes = encoder.Create(mesh); Assert.True(wroteBytes > 0); Assert.True(encoder.FinaliseEncoding()); // Allocate a reader. Contains a CollatedPacketDecoder. System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(encoder.Buffer, 0, encoder.Count); PacketStreamReader decoder = new PacketStreamReader(memoryStream); PacketBuffer packet; MeshShape readMesh = new MeshShape(); int packetCount = 0; long processedBytes = 0; while ((packet = decoder.NextPacket(ref processedBytes)) != null) { NetworkReader reader = new NetworkReader(packet.CreateReadStream(true)); ++packetCount; Assert.True(packet.ValidHeader); Assert.Equal(packet.Header.Marker, PacketHeader.PacketMarker); Assert.Equal(packet.Header.VersionMajor, PacketHeader.PacketVersionMajor); Assert.Equal(packet.Header.VersionMinor, PacketHeader.PacketVersionMinor); Assert.Equal(packet.Header.RoutingID, mesh.RoutingID); // Peek the shape ID. uint shapeId = packet.PeekUInt32(PacketHeader.Size); Assert.Equal(shapeId, mesh.ID); switch ((ObjectMessageID)packet.Header.MessageID) { case ObjectMessageID.Create: Assert.True(readMesh.ReadCreate(packet, reader)); break; case ObjectMessageID.Update: Assert.True(readMesh.ReadUpdate(packet, reader)); break; case ObjectMessageID.Data: Assert.True(readMesh.ReadData(packet, reader)); break; } } Assert.True(packetCount > 0); // FIXME: Does not match, but results are fine. processedBytes is 10 greater than wroteBytes. //Assert.Equal(processedBytes, wroteBytes); // Validate what we've read back. ShapeTestFramework.ValidateShape(readMesh, mesh, new Dictionary <ulong, Resource>()); }
protected override void OnCreateScene(Mesh[] meshes, MeshObject[] meshObjects, Light[] lights, ColorValue shadowColor, bool calculateShadows) { //create separated physics scene physicsScene = PhysicsWorld.Instance.CreateScene("Static Lighting"); //initialize contact group physicsScene.SpecialContactGroupsEnabled = true; physicsScene.SetupSpecialContactGroups(1, 1, true); Dictionary <Mesh, string> meshPhysicsMeshNames = new Dictionary <Mesh, string>(); //register physics custom mesh names foreach (Mesh mesh in meshes) { string customMeshName = PhysicsWorld.Instance.AddCustomMeshGeometry( mesh.Positions, mesh.Indices, null, MeshShape.MeshTypes.TriangleMesh, 0, 0, false); meshPhysicsMeshNames.Add(mesh, customMeshName); } //create bodies foreach (MeshObject meshObject in meshObjects) { Body body = physicsScene.CreateBody(); body.Static = true; body.Position = meshObject.Position; body.Rotation = meshObject.Rotation; body.UserData = meshObject; MeshShape shape = body.CreateMeshShape(); shape.ContactGroup = contactGroup; shape.MeshName = meshPhysicsMeshNames[meshObject.Mesh]; shape.MeshScale = meshObject.Scale; body.PushedToWorld = true; } //lights { this.lights = new MyLight[lights.Length]; for (int n = 0; n < lights.Length; n++) { Light light = lights[n]; MyLight myLight = null; PointLight pointLight = light as PointLight; if (pointLight != null) { myLight = new MyPointLight(pointLight); } SpotLight spotLight = light as SpotLight; if (spotLight != null) { myLight = new MySpotLight(spotLight); } DirectionalLight directionalLight = light as DirectionalLight; if (directionalLight != null) { myLight = new MyDirectionalLight(directionalLight); } if (myLight == null) { Log.Fatal("SimpleStaticLightingCalculationWorld.OnCreateScene: not implemented light type."); } this.lights[n] = myLight; this.lights[n].Initialize(); } } this.shadowColor = shadowColor; this.calculateShadows = calculateShadows; }
public void ValidateMeshShape(Shape shapeArg, Shape referenceArg, Dictionary <ulong, Resource> resources) { ShapeTestFramework.ValidateShape(shapeArg, referenceArg, resources); MeshShape shape = (MeshShape)shapeArg; MeshShape reference = (MeshShape)referenceArg; Assert.Equal(shape.DrawType, reference.DrawType); if (reference.Vertices != null) { Assert.NotNull(shape.Vertices); Assert.Equal(reference.Vertices.Length, shape.Vertices.Length); bool verticesMatch = true; for (int i = 0; i < shape.Vertices.Length; ++i) { if (reference.Vertices[i] != shape.Vertices[i]) { verticesMatch = false; _output.WriteLine("vertex mismatch [{0}] : ({1},{2},{3}) != ({4},{5},{6})", i, reference.Vertices[i].X, reference.Normals[i].Y, reference.Normals[i].Z, shape.Normals[i].X, shape.Normals[i].Y, shape.Normals[i].Z); } } Assert.True(verticesMatch); } if (reference.Normals != null) { Assert.NotNull(shape.Normals); Assert.Equal(reference.Normals.Length, shape.Normals.Length); bool normalsMatch = true; for (int i = 0; i < shape.Normals.Length; ++i) { if (reference.Normals[i].X != shape.Normals[i].X || reference.Normals[i].Y != shape.Normals[i].Y || reference.Normals[i].Z != shape.Normals[i].Z) { normalsMatch = false; _output.WriteLine("normal mismatch [{0}] : ({1},{2},{3}) != ({4},{5},{6})", i, reference.Normals[i].X, reference.Normals[i].Y, reference.Normals[i].Z, shape.Normals[i].X, shape.Normals[i].Y, shape.Normals[i].Z); } } Assert.True(normalsMatch); } if (reference.Colours != null) { Assert.NotNull(shape.Colours); Assert.Equal(reference.Colours.Length, shape.Colours.Length); bool coloursMatch = true; for (int i = 0; i < shape.Colours.Length; ++i) { if (reference.Colours[i] != shape.Colours[i]) { _output.WriteLine("colour mismatch [{0}] : 0x{1} != 0x{2}", i, reference.Colours[i].ToString("x"), shape.Colours[i].ToString("x")); coloursMatch = false; } } Assert.True(coloursMatch); } if (reference.Indices != null) { Assert.NotNull(shape.Indices); Assert.Equal(reference.Indices.Length, shape.Indices.Length); bool indicesMatch = true; for (int i = 0; i < shape.Indices.Length; ++i) { if (reference.Indices[i] != shape.Indices[i]) { _output.WriteLine("index mismatch [{0}] : {1} != {2}", i, reference.Indices[i], shape.Indices[i]); indicesMatch = false; } } Assert.True(indicesMatch); } }