int CheckAndRequestTextures(BlenderObject bo) { List <string> boTextures = bo.Textures; Debug.LogFormat("{0} has {1} textures", bo.name, boTextures.Count); if (boTextures.Count > 0) { for (int i = boTextures.Count - 1; i >= 0; i--) { if (HasTexture(boTextures[i])) { boTextures.RemoveAt(i); } } if (boTextures.Count == 0) { return(0); } // temporarily limit to 1 texture (simplify request handling) while (boTextures.Count > 1) { boTextures.RemoveAt(boTextures.Count - 1); } byte[] data = null; // request textures using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter br = new BinaryWriter(ms)) { br.Write(TYPE_MATERIAL_TEXTURE_REQUEST); br.Write(0); // packet size placeholder br.Write(boTextures.Count); foreach (var tex in boTextures) { Debug.LogFormat("Requesting image {0}", tex); br.Write(tex); } } data = ms.ToArray(); UpdateSize(ref data, 1); } Debug.Log("Sending TYPE_MATERIAL_TEXTURE_REQUEST packet"); blenderService.SendData(data); return(boTextures.Count); } return(0); }
public override void Bind(BlenderObject bo) { // transform matrix transform.localPosition = bo.matrix.GetTranslation(); transform.localRotation = bo.matrix.GetRotation(); transform.localScale = bo.matrix.GetScale(); // mesh if (bo.HasMesh) { MeshFilter mf = GetComponent <MeshFilter>(); var mesh = new Mesh(); mf.mesh = mesh; mesh.vertices = bo.verts; mesh.normals = bo.normals; mesh.uv = bo.uvs; mesh.triangles = bo.faces; mesh.RecalculateBounds(); } // materials if (bo.HasMaterials) { MeshRenderer mr = GetComponent <MeshRenderer>(); // temporarily supporting a single material mr.sharedMaterial = CreateMaterial(bo.materials[0]); } // children if (bo.HasChildren) { foreach (var i in Enumerable.Range(0, bo.children.Length)) { BlenderObject boChild = bo.children[i]; // has child? Transform tChild = transform.Find(boChild.name); if (tChild == null) { GameObject goChild = new GameObject(boChild.name); goChild.AddComponent <BlenderGameObject>(); tChild = goChild.transform; tChild.parent = transform; } BlenderGameObject bgoChild = tChild.GetComponent <BlenderGameObject>(); bgoChild.Bind(boChild); } } }
public override void Bind(BlenderObject bo) { if (transform.childCount == 0) { GameObject childGO = new GameObject(bo.name); BlenderGameObject childBGO = childGO.AddComponent <BlenderGameObject>(); childBGO.transform.parent = transform; } transform.GetChild(0).GetComponent <BaseBlenderGameObject>().Bind(bo); // world anchor if (bo.worldAnchor != null) { Debug.Log("Anchor received from service"); SetAnchor(bo.worldAnchor); } }
int CheckAndRequestWorldAnchor(BlenderObject bo) { if (!bo.worldAnchorSet) { return(0); } if (bo.worldAnchor != null && bo.worldAnchor.Length > 0) { return(0); } if (blenderGameObjects.ContainsKey(bo.name)) { if (blenderGameObjects[bo.name].IsAnchored) { return(0); } } byte[] data = null; // request textures using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter br = new BinaryWriter(ms)) { br.Write(TYPE_OBJECT_WORLDANCHOR_REQUEST); br.Write(0); // packet size placeholder br.Write(bo.name); } data = ms.ToArray(); UpdateSize(ref data, 1); } Debug.Log("Sending TYPE_OBJECT_WORLDANCHOR_REQUEST packet"); blenderService.SendData(data); return(1); }
// These files can be created using binary blender objects public string ReadBinaryFile(string filename) { string BlenderFilesDirectory = GlsTutorialsClass.ProjectDirectory + @"/Blender/"; blenderObjects = new List<BlenderObject>(); int offset = 0; StringBuilder result = new StringBuilder(); byte[] binaryBlenderObjects = File.ReadAllBytes(BlenderFilesDirectory + filename); int objectCount = BitConverter.ToInt32 (binaryBlenderObjects, 0); result.AppendLine("Found " + objectCount.ToString() + " Blender Objects"); offset = offset + 4; for (int i = 0; i < objectCount; i++) { BlenderObject bo = new BlenderObject("Object" + i.ToString()); int blenderObjectSize = bo.CreateFromBinaryData(binaryBlenderObjects, offset); offset = offset + blenderObjectSize; result.AppendLine("Object " + i.ToString() + " size = " + blenderObjectSize.ToString()); bo.Setup(); blenderObjects.Add(bo); } return result.ToString(); }
void ProcessBlenderObject(BlenderObject bo) { if (CheckAndRequestTextures(bo) > 0) { blenderObjectsToBeProcessed.Add(bo); return; } if (CheckAndRequestWorldAnchor(bo) > 0) { blenderObjectsToBeProcessed.Add(bo); return; } BaseBlenderGameObject bgo; bool bgoCreated = false; if (!blenderGameObjects.ContainsKey(bo.name)) { GameObject go = new GameObject(bo.name); bgo = go.AddComponent <AnchoredBlenderGameObject>(); go.transform.parent = BlenderObjectsContainer != null ? BlenderObjectsContainer.transform : transform; blenderGameObjects.Add(bo.name, bgo); bgoCreated = true; } bgo = blenderGameObjects[bo.name]; bgo.Bind(bo); if (bgoCreated) { OnBlenderGameObjectCreated(bgo); } else { OnBlenderGameObjectUpdated(bgo); } }
/*! This methode creates the game object of new mesh and runs as coroutine. * The loaded meshs are splitted in little part. Only on part of a mesh will be process each frame */ private IEnumerator LoadFileExecute() { Bounds bounds = new Bounds(); bool boundsInitialized = false; // set to true when bounds is first set // meshNode // | - containerObject // | - actual mesh // | - actual mesh // | - actual mesh // | - ... // | - containerObject // | - actual mesh // | - actual mesh // | - actual mesh // | - ... // | ... foreach (List <UnityMesh> um in unityMeshes) { GameObject containerObject = new GameObject(um[0].Name); containerObject.layer = meshNode.layer; //Set same layer as parent containerObject.transform.SetParent(meshNode.transform, false); //containerObject.transform.localScale = new Vector3 (400.0f, 400.0f, 400.0f); containerObject.transform.localPosition = new Vector3(0, 0, 0); MeshMaterialControl matControl = containerObject.AddComponent <MeshMaterialControl> (); Color col = matColorForMeshName(um[0].Name); matControl.materialColor = col; MeshGameObjectContainers.Add(containerObject); //attach BlenderObject to containerObject foreach (BlenderObjectBlock b in blenderObjects) { if (b.uniqueIdentifier == um[0].UniqueIdentifier) { BlenderObject attachedObject = containerObject.AddComponent <BlenderObject>(); //TODO Remove... maybe attachedObject.objectName = b.objectName; attachedObject.location = b.location; attachedObject.rotation = b.rotation; //Convert to left-handed soordinate systems containerObject.transform.localPosition = new Vector3(b.location.x, b.location.y, -b.location.z); /* TODO * Quaternion rot = Quaternion.Inverse(b.rotation); * rot = new Quaternion(-rot.x, -rot.z, rot.y, -rot.w); * containerObject.transform.localRotation = rot; */ } } foreach (UnityMesh unityMesh in um) { //Spawn object GameObject objToSpawn = new GameObject(unityMesh.Name); objToSpawn.layer = meshNode.layer; //Set same layer as parent objToSpawn.transform.SetParent(containerObject.transform, false); //Add Components objToSpawn.AddComponent <MeshFilter>(); objToSpawn.AddComponent <MeshCollider>(); //TODO need to much time --> own thread?? Dont work in Unity!! objToSpawn.AddComponent <MeshRenderer>(); //Create Mesh Mesh mesh = new Mesh(); mesh.name = unityMesh.Name; mesh.vertices = unityMesh.VertexList; mesh.normals = unityMesh.NormalList; mesh.triangles = unityMesh.TriangleList; objToSpawn.GetComponent <MeshFilter>().mesh = mesh; objToSpawn.GetComponent <MeshCollider>().sharedMesh = mesh; //TODO Reduce mesh?? objToSpawn.transform.localPosition = new Vector3(0, 0, 0); unityMeshes = new List <List <UnityMesh> >(); loaded = false; Path = ""; // Increase the common bounding box to contain this object: // Calculate bounds in Bounds worldBounds = TransformUtil.TransformBounds(objToSpawn.transform.parent, mesh.bounds); Bounds localBounds = TransformUtil.InverseTransformBounds(containerObject.transform.parent, worldBounds); if (!boundsInitialized) { bounds = localBounds; boundsInitialized = true; } else { bounds.Encapsulate(localBounds); } // Let others know that a new mesh has been loaded: PatientEventSystem.triggerEvent(PatientEventSystem.Event.MESH_LoadedSingle, objToSpawn); // Make sure the color of the material is set correctly: matControl.changeOpactiyOfChildren(1f); // Deactivate for now, let someone else activate the mesh when needed: objToSpawn.SetActive(false); yield return(null); } } // Move the object by half the size of all of the meshes. // This makes sure the object will rotate around its actual center: //containerObject.transform.localPosition = -bounds.center; meshNode.GetComponent <ModelMover> ().targetPosition = Vector3.Scale(-bounds.center, meshNode.transform.localScale); triggerEvent = true; yield return(null); }
public static BlenderObject CreateFromByteStream(BinaryReader br) { var bo = new BlenderObject(); // name bo.name = br.ReadString(); // mode bo.mode = br.ReadString(); // transform ( bo.matrix = Matrix4x4.identity; foreach (var i in Enumerable.Range(0, 16)) { bo.matrix[i] = br.ReadSingle(); } bool meshDataAvailable = br.ReadByte() > 0; if (meshDataAvailable) { // verts int vertsCount = br.ReadInt32(); bo.verts = new Vector3[vertsCount / 3]; int vertsIndex = 0; for (var i = 0; i < vertsCount; i += 3) { bo.verts[vertsIndex] = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); vertsIndex++; } // normals int normalsCount = br.ReadInt32(); bo.normals = new Vector3[normalsCount / 3]; int normalIndex = 0; for (var i = 0; i < normalsCount; i += 3) { bo.normals[normalIndex] = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); normalIndex++; } // faces int facesCount = br.ReadInt32(); bo.faces = new int[facesCount]; int faceIndex = 0; for (var i = 0; i < facesCount; i += 1) { bo.faces[faceIndex] = br.ReadInt32(); faceIndex++; } // uvs int uvsCount = br.ReadInt32(); bo.uvs = null; if (uvsCount > 0) { bo.uvs = new Vector2[uvsCount / 2]; int uvIdex = 0; for (var i = 0; i < uvsCount; i += 2) { bo.uvs[uvIdex] = new Vector2(br.ReadSingle(), br.ReadSingle()); uvIdex++; } } // materials int materialsCount = br.ReadInt32(); bo.materials = null; if (materialsCount > 0) { bo.materials = new BlenderObjectMaterial[materialsCount]; for (int i = 0; i < materialsCount; i++) { bo.materials[i] = BlenderObjectMaterial.CreateFromByteStream(br); } } } // chilren int childrenCount = br.ReadInt32(); bo.children = null; if (childrenCount > 0) { bo.children = new BlenderObject[childrenCount]; for (int i = 0; i < childrenCount; i++) { bo.children[i] = BlenderObject.CreateFromByteStream(br); } } return(bo); }
public void ReadFile(string filename) { string BlenderFilesDirectory = GlsTutorialsClass.ProjectDirectory + @"/Blender/"; string nextLine; blenderObjects = new List<BlenderObject>(); using (StreamReader sr = new StreamReader(new FileStream(BlenderFilesDirectory + filename, FileMode.Open))) { short vertexCount = 1; short normalCount = 1; short previousObjectVertexCount = 1; // change from 1 to zero based short previousObjectNormalCount = 1; // change from 1 to zero based nextLine = sr.ReadLine(); while (!sr.EndOfStream) { if (nextLine[0] == 'o') { BlenderObject bo = new BlenderObject(nextLine); while (!sr.EndOfStream) { nextLine = sr.ReadLine(); if (nextLine[0] == 'o') break; if (nextLine[0] == 'v') { if (nextLine[1] == ' ') { bo.AddVertex(nextLine); vertexCount++; } if (nextLine[1] == 'n') { bo.AddNormal(nextLine); normalCount++; } } if (nextLine[0] == 'f') { bo.AddTriangle(nextLine, previousObjectVertexCount, previousObjectNormalCount); } } previousObjectVertexCount = vertexCount; previousObjectNormalCount = normalCount; bo.Setup(); blenderObjects.Add(bo); } else { if (!sr.EndOfStream) nextLine = sr.ReadLine(); } } } }
public virtual void Bind(BlenderObject bo) { throw new NotImplementedException(); }
void ProcessData(byte[] data) { using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { byte packetType = br.ReadByte(); int packetSize = br.ReadInt32(); if (packetType == TYPE_OBJECT_UPDATE) { Debug.Log("TYPE_OBJECT_UPDATE"); BlenderObject bo = null; // metadata string tag = br.ReadString(); float timestamp = br.ReadSingle(); string updatedObject = br.ReadString(); string updatedMode = br.ReadString(); bool worldAnchorSet = br.ReadByte() > 0; bo = BlenderObject.CreateFromByteStream(br); bo.worldAnchorSet = worldAnchorSet; // correct matrix bo.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(-90, 0, 0), new Vector3(.1f, .1f, .1f)) * bo.matrix; if (bo != null) { ProcessBlenderObject(bo); } } else if (packetType == TYPE_MATERIAL_TEXTURE) { Debug.Log("TYPE_MATERIAL_TEXTURE"); int count = br.ReadByte(); for (int i = 0; i < count; i++) { int width = br.ReadInt32(); int height = br.ReadInt32(); int textureLength = br.ReadInt32(); byte[] textureData = br.ReadBytes(textureLength); string textureName = br.ReadString(); Debug.LogFormat("TYPE_MATERIAL_TEXTURE {0}", textureName); Texture2D tex = new Texture2D(width, height); if (tex.LoadImage(textureData)) { textures[textureName] = tex; } else { Debug.LogWarningFormat("Failed to load texture {0}", textureName); } } for (int i = blenderObjectsToBeProcessed.Count - 1; i >= 0; i--) { BlenderObject bo = blenderObjectsToBeProcessed[i]; if (CheckAndRequestTextures(bo) == 0) { blenderObjectsToBeProcessed.RemoveAt(i); ProcessBlenderObject(bo); } } } else if (packetType == TYPE_OBJECT_REMOVED) { Debug.Log("TYPE_OBJECT_REMOVED"); string boName = br.ReadString(); Debug.LogFormat("Removing BGO {0}", boName); if (blenderGameObjects.ContainsKey(boName)) { var bgo = blenderGameObjects[boName]; blenderGameObjects.Remove(boName); Destroy(bgo.gameObject); OnBlenderGameObjectDestoryed(boName); } } else if (packetType == TYPE_OBJECT_WORLDANCHOR) { Debug.Log("TYPE_OBJECT_WORLDANCHOR"); string boName = br.ReadString(); int worldAnchorDataSize = br.ReadInt32(); byte[] worldAnchorData = br.ReadBytes(worldAnchorDataSize); Debug.LogFormat("Setting world anchor for BGO {0}, count {1}", boName, worldAnchorDataSize); // update existing Blender Object if (blenderGameObjects.ContainsKey(boName)) { var bgo = blenderGameObjects[boName]; bgo.SetAnchor(worldAnchorData); OnBlenderGameObjectUpdated(bgo); } // update pending BlenderObject for (int i = blenderObjectsToBeProcessed.Count - 1; i >= 0; i--) { BlenderObject bo = blenderObjectsToBeProcessed[i]; if (bo.name.Equals(boName, StringComparison.OrdinalIgnoreCase)) { blenderObjectsToBeProcessed.RemoveAt(i); bo.worldAnchor = worldAnchorData; ProcessBlenderObject(bo); } } } else if (packetType == TYPE_OBJECT_OPERATION) { Debug.Log("TYPE_OBJECT_OPERATION"); // TODO } } } }