public ThreeSceneRoot Run(UnitySceneRoot unityscene) { // three.js는 scene밑에 모든게 들어간다 // 그래서 기본적인 계층 구조를 미리 만들어야한다 // 계층 구조 - begin foreach (var n in unityscene.GraphNodeTable.GetEnumerable <GameObjectNode>()) { n.BuildHierarchy(unityscene.GraphNodeTable); } var objroot = new RootGameObjectNode(); objroot.BuildHierarchy(unityscene.GraphNodeTable); root.Root = VisitGameObjectNode_r(objroot); // 계층 구조 - end // ambient light 같은거 + 기타 속성 Visit(unityscene.Settings); // 공유 속성 foreach (var n in unityscene.ContainerTable.GetEnumerable <TextureContainer>()) { RegisterTexture(n); } foreach (var n in unityscene.ContainerTable.GetEnumerable <LightmapContainer>()) { RegisterLightmap(n); } // lightmap이 없는 경우 foreach (var n in unityscene.ContainerTable.GetEnumerable <MeshContainer>()) { RegisterMeshWithoutLightmap(n); } // 게임오브젝트마다 별도의 Mesh를 등록하는게 가능하도록 // 왜냐하면 lightmap 좌표 정보는 lightmapScaleOffset는 Renderer에 저장되기때문 // lightmap이 있는 경우 foreach (var n in unityscene.GraphNodeTable.GetEnumerable <GameObjectNode>()) { if (!n.HasLightmap) { continue; } var renderer = n.CurrentObject.GetComponent <Renderer>(); var meshfilter = n.CurrentObject.GetComponent <MeshFilter>(); if (renderer == null) { continue; } if (meshfilter == null) { continue; } var meshcontainerkey = meshfilter.sharedMesh.GetInstanceID().ToString(); var meshcontainer = unityscene.ContainerTable.Get <MeshContainer>(meshcontainerkey); AbstractGeometryElem geo = new BufferGeometryElem(meshcontainer, n.HasLightmap, n.lightmapScaleOffset); var geokey = ConvertKeyForBufferGeometryElem(renderer); root.SharedNodeTable.Add(geo, geokey); } foreach (var n in unityscene.ContainerTable.GetEnumerable <MaterialContainer>()) { var mtl = CreateMaterialElem(n); root.SharedNodeTable.Add(mtl, n.InstanceId); } foreach (var n in unityscene.GraphNodeTable.GetEnumerable <GameObjectNode>()) { if (!n.HasLightmap) { continue; } var renderer = n.CurrentObject.GetComponent <Renderer>(); if (renderer == null) { continue; } var mtl = renderer.sharedMaterial; var mtlcontainer = unityscene.ContainerTable.Get <MaterialContainer>(mtl.GetInstanceID().ToString()); var mtlelem = CreateMaterialElem(mtlcontainer); var lightmapkey = renderer.lightmapIndex.ToString(); var lightmapelem = root.SharedNodeTable.Get <TextureElem>(lightmapkey); mtlelem.LightMap = lightmapelem; var key = ConvertKeyForMaterialELem(renderer); root.SharedNodeTable.Add(mtlelem, key); } // Object3D와 관련된 객체 var lightelems = new List <LightElem>(); foreach (var n in unityscene.GraphNodeTable.GetEnumerable <LightNode>()) { var lightelem = RegisterToThreeScene(n); lightelems.Add(lightelem); } var camelems = new List <CameraElem>(); foreach (var n in unityscene.GraphNodeTable.GetEnumerable <CameraNode>()) { var camelem = RegisterToThreeScene(n); camelems.Add(camelem); } var meshelems = new List <MeshElem>(); foreach (var n in unityscene.GraphNodeTable.GetEnumerable <RenderNode>()) { var meshelem = RegisterToThreeScene(n); meshelems.Add(meshelem); } // 연관된 스크립트 변수 등록 foreach (var n in unityscene.GraphNodeTable.GetEnumerable <ScriptNode>()) { var objnode = objNodeTable[n.CurrentObject.GetInstanceID().ToString()]; RegisterScriptVariables(unityscene, objnode, n); } // Optimize scene graph // 특정 객체를 포함하는 Group에 다른 객체가 등록되어있지 않은 경우, cam을 위로 올릴수 있다 // 처음부터 객체를 바로 생성하지 않고 자식이 1개인 경우에만 끌어올리는 이유는 // 유니티 game object안에는 light, mesh 같은게 동시에 들어갈수 있지만 three.js에서는 불가능하기때문 foreach (var cam in camelems) { UpcastInSceneThreeObject3D(cam); } foreach (var light in lightelems) { UpcastInSceneThreeObject3D(light); } foreach (var child in meshelems) { UpcastInSceneThreeObject3D(child); } return(root); }
public ThreeSceneRoot Run(UnitySceneRoot unityscene) { // three.js는 scene밑에 모든게 들어간다 // 그래서 기본적인 계층 구조를 미리 만들어야한다 // 계층 구조 - begin foreach (var n in unityscene.GraphNodeTable.GetEnumerable <GameObjectNode>()) { n.BuildHierarchy(unityscene.GraphNodeTable); } var objroot = new RootGameObjectNode(); objroot.BuildHierarchy(unityscene.GraphNodeTable); root.Root = VisitGameObjectNode_r(objroot); // 계층 구조 - end // ambient light 같은거 + 기타 속성 Visit(unityscene.Settings); // 공유 속성 foreach (var n in unityscene.ContainerTable.GetEnumerable <TextureContainer>()) { RegisterTexture(n); } foreach (var n in unityscene.ContainerTable.GetEnumerable <LightmapContainer>()) { RegisterLightmap(n); } foreach (var n in unityscene.ContainerTable.GetEnumerable <MaterialContainer>()) { RegisterMaterial(n); } foreach (var n in unityscene.ContainerTable.GetEnumerable <MeshContainer>()) { RegisterMesh(n); } // Object3D와 관련된 객체 var lightelems = new List <LightElem>(); foreach (var n in unityscene.GraphNodeTable.GetEnumerable <LightNode>()) { var lightelem = RegisterToThreeScene(n); lightelems.Add(lightelem); } var camelems = new List <CameraElem>(); foreach (var n in unityscene.GraphNodeTable.GetEnumerable <CameraNode>()) { var camelem = RegisterToThreeScene(n); camelems.Add(camelem); } var meshelems = new List <MeshElem>(); foreach (var n in unityscene.GraphNodeTable.GetEnumerable <RenderNode>()) { var meshelem = RegisterToThreeScene(n); meshelems.Add(meshelem); } // 연관된 스크립트 변수 등록 foreach (var n in unityscene.GraphNodeTable.GetEnumerable <ScriptNode>()) { var objnode = objNodeTable[n.CurrentObject.GetInstanceID()]; RegisterScriptVariables(unityscene, objnode, n); } // Optimize scene graph // 특정 객체를 포함하는 Group에 다른 객체가 등록되어있지 않은 경우, cam을 위로 올릴수 있다 // 처음부터 객체를 바로 생성하지 않고 자식이 1개인 경우에만 끌어올리는 이유는 // 유니티 game object안에는 light, mesh 같은게 동시에 들어갈수 있지만 three.js에서는 불가능하기때문 foreach (var cam in camelems) { UpcastInSceneThreeObject3D(cam); } foreach (var light in lightelems) { UpcastInSceneThreeObject3D(light); } foreach (var child in meshelems) { UpcastInSceneThreeObject3D(child); } return(root); }