protected void ProcessUpdate(GeometryNode Update) { GameObject node = GetCreateObject(Update); SetTransform(node, Update.Transform); MeshFilter meshFilter = node.GetComponent<MeshFilter>(); if (meshFilter == null) { meshFilter = node.AddComponent<MeshFilter>(); } MeshRenderer meshRenderer = node.GetComponent<MeshRenderer>(); if (meshRenderer == null) { meshRenderer = node.AddComponent<MeshRenderer>(); } if (meshFilter.sharedMesh == null) { meshFilter.mesh = new Mesh(); } UnityStyleMesh meshsource = ConvertMeshToUnityStyle(Update); SetMeshContent(meshFilter.sharedMesh, meshsource); SetMaterials(meshRenderer, meshsource, Update); }
protected GameObject GetCreateObject(GeometryNode update) { GameObject node = GameObject.Find(update.Name); if (node == null) { node = new GameObject(update.Name); } if (update.Parent != null && update.Parent != "Scene Root") { Debug.Log("Hierarchical processing not implemented yet."); } return node; }
protected unsafe GeometryNode CreateGeometryUpdate(IINode node, ITriObject maxGeometry) { GeometryNode update = new GeometryNode(); update.Name = node.Name; update.Parent = node.ParentNode.Name; update.Transform = GetTransform(node); /* * Scene objects have one, or none, material. This member will be that materials name, even if that material is a container like a Composite * or Shell material. * The client will attach the Material ID of the face when/if the materials are split out, which will allow the materials * processing code to identify and import the correct material properties later. (In practice, we dont even need to store this - since knowing * the node name will allow us to find it - but sending it allows us to match the functionality of the FBX importer. */ if (node.Mtl != null) { update.MaterialName = node.Mtl.Name; } IMesh mesh = maxGeometry.Mesh; /* Get the master face array and vertex positions. We split by material id here also for convenience. */ var facesAndPositions = GetTriMeshFacesAndPositions(mesh); update.FaceGroups.AddRange(MakeFaceGroupsFromMaterialIds(facesAndPositions.face_materialIds)); update.faceFlags = facesAndPositions.face_flags; update.Channels.Add(facesAndPositions.positions_channel); /* Get the remaining properties, such as normals and texture coordinates */ update.Channels.Add(GetTriMeshNormals(mesh)); update.Channels.AddRange(GetTriMeshMapChannels(mesh)); return update; }
protected void SetMaterials(MeshRenderer renderer, UnityStyleMesh meshsrc, GeometryNode update) { MaterialIDsMap map = renderer.gameObject.AddComponent<MaterialIDsMap>(); Material[] materials = new Material[meshsrc.face_groups.Count]; for (int i = 0; i < meshsrc.face_groups.Count; i++) { map.m_materialIds.Add(meshsrc.face_groups[i].MaterialId); Material m = new Material(Shader.Find("Diffuse")); m.name = update.MaterialName; materials[i] = m; } renderer.materials = materials; }
/// <summary> /// Processes update with heterogenous vertex component arrays into a single set of homogenous arrays based on face data, and calculates tangents /// </summary> /// <param name="Update"></param> /// <returns></returns> protected UnityStyleMesh ConvertMeshToUnityStyle(GeometryNode Update) { /* In Max, and the portable mesh, each triangle is made of a number of faces superimposed on eachother. Those faces contain indices into different vertex arrays. * The vertex arrays contain positions, texture coords, normals, etc. This function flattens these, so each face is made up of 3 sets of 4 indices. One set for * each corner, and the sets containing the indices into the various vertex arrays referenced by the original 'sub'-faces. */ var positionChannel = ChannelExtensions.GetPositionChannel(Update.Channels); var normalChannel = ChannelExtensions.GetNormalsChannel(Update.Channels); var texture_tChannel = ChannelExtensions.GetTextureChannel(Update.Channels, VertexChannelType.Texture1); var texture_yChannel = ChannelExtensions.GetTextureChannel(Update.Channels, VertexChannelType.Texture2); var faceTripletGroups = CreateFaceTripletGroups(Update.FaceGroups, positionChannel, normalChannel, texture_tChannel, texture_yChannel); /* For each face triple (set of 4 indices), dereference it so they all become indices into a single master list of triplets. This master list can then * be used to create a vertex array. */ var triplets = new FaceTriplets(); var faceindexgroups = DereferenceFaceTripletGroups(faceTripletGroups, triplets).ToList(); /* Build the vertex component arrays based on the master triplet array created above */ var vertexcomponents = BuildVertexComponents(triplets, positionChannel.m_vertices, normalChannel.m_vertices, texture_tChannel.m_vertices, texture_yChannel.m_vertices); return new UnityStyleMesh { components = vertexcomponents, face_groups = faceindexgroups }; }