/// <summary> /// /// </summary> /// <param name="gizmoMap"></param> /// <param name="parent"></param> private void setupGizmos(Hashtable gizmoMap, Object3D parent) { foreach (DictionaryEntry name in gizmoMap) { for (int i = ((ArrayList)gizmoMap[name.Key]).Count; i-- > 0;) { var map = (ArrayList)((ArrayList)gizmoMap[name.Key])[i]; var object3D = (Object3D)map[0]; ArrayList position = null; if (map.Count > 1) { position = (ArrayList)map[1]; } ArrayList rotation = null; if (map.Count > 2) { rotation = (ArrayList)map[2]; } object3D.Name = (string)name.Key; if (null != position) { object3D.Position.set((float)position[0], (float)position[1], (float)position[2]); } if (null != rotation) { object3D.Rotation.set((float)rotation[0], (float)rotation[1], (float)rotation[2]); } parent.Add(object3D); } } }
/// <summary> /// /// </summary> /// <param name="control"></param> public override void Load(Control control) { base.Load(control); camera = new PerspectiveCamera(70, control.Width / (float)control.Height, 1, 1000); this.camera.Position.Z = 400; scene = new Scene(); scene.Fog = new Fog(Color.Black, 1, 1000); object3D = new Object3D(); scene.Add(object3D); var geometry = new SphereGeometry(1, 4, 4); var material = new MeshPhongMaterial() { Color = Color.White, Shading = ThreeCs.Three.FlatShading }; for (var i = 0; i < 100; i++) { var mesh = new Mesh(geometry, material); mesh.Position.set(Mat.Random() - 0.5f, Mat.Random() - 0.5f, Mat.Random() - 0.5f).Normalize(); mesh.Position.MultiplyScalar(Mat.Random() * 400); mesh.Rotation.set(Mat.Random() * 2, Mat.Random() * 2, Mat.Random() * 2); mesh.Scale.X = mesh.Scale.Y = mesh.Scale.Z = Mat.Random() * 50; object3D.Add(mesh); } scene.Add(new AmbientLight((Color)colorConvertor.ConvertFromString("#222222"))); light = new DirectionalLight(Color.White); light.Position.set(1, 1, 1); scene.Add(light); // postprocessing composer = new EffectComposer(renderer, control); composer.AddPass(new RenderPass(scene, camera)); var effect1 = new ShaderPass(new DotScreenShader()); effect1.Uniforms["scale"]["value"] = 4; composer.AddPass(effect1); var effect2 = new ShaderPass(new RGBShiftShader()); effect2.Uniforms["amount"]["value"] = 0.0015f; effect2.RenderToScreen = true; composer.AddPass(effect2); }
/// <summary> /// /// </summary> /// <param name="control"></param> public override void Load(Control control) { base.Load(control); camera = new PerspectiveCamera(60, control.Width / (float)control.Height, 1, 10000); this.camera.Position.Z = 500; scene = new Scene(); scene.Fog = new Fog(Color.White, 1, 10000); var geometry = new BoxGeometry(100, 100, 100); var material = new MeshNormalMaterial(); group = new Object3D(); for (var i = 0; i < 1000; i++) { var mesh = new Mesh(geometry, material); mesh.Position.X = Mat.Random() * 2000 - 1000; mesh.Position.Y = Mat.Random() * 2000 - 1000; mesh.Position.Z = Mat.Random() * 2000 - 1000; mesh.Rotation.X = (float)(Mat.Random() * 2.0 * Math.PI); mesh.Rotation.Y = (float)(Mat.Random() * 2.0 * Math.PI); mesh.MatrixAutoUpdate = false; mesh.UpdateMatrix(); group.Add(mesh); } scene.Add(group); renderer.SetClearColor(Color.White); renderer.SortObjects = false; }
/// <summary> /// /// </summary> /// <param name="control"></param> public override void Load(Control control) { base.Load(control); camera = new PerspectiveCamera(70, control.Width / (float)control.Height, 1, 10000); scene = new Scene(); var sphereGeometry = new SphereGeometry(5); var material = new MeshBasicMaterial() { Color = Color.Red }; sphereInter = new Mesh(sphereGeometry, material); sphereInter.Visible = false; scene.Add(sphereInter); var geometry = new Geometry(); var point = new Vector3(); var direction = new Vector3(); for (var i = 0; i < 100; i++) { direction.X += Mat.Random() - 0.5f; direction.Y += Mat.Random() - 0.5f; direction.Z += Mat.Random() - 0.5f; direction.Normalize().MultiplyScalar(5); point.Add(direction); geometry.Vertices.Add((Vector3)point.Clone()); } parentTransform = new Object3D(); parentTransform.Position.X = Mat.Random() * 40 - 20; parentTransform.Position.Y = Mat.Random() * 40 - 20; parentTransform.Position.Z = Mat.Random() * 40 - 20; parentTransform.Rotation.X = Mat.Random() * 2 * (float)Math.PI; parentTransform.Rotation.Y = Mat.Random() * 2 * (float)Math.PI; parentTransform.Rotation.Z = Mat.Random() * 2 * (float)Math.PI; parentTransform.Scale.X = Mat.Random() + 0.5f; parentTransform.Scale.Y = Mat.Random() + 0.5f; parentTransform.Scale.Z = Mat.Random() + 0.5f; for (var i = 0; i < 50; i++) { var type = Mat.Random() > 0.5f ? Three.LineStrip : Three.LinePieces; var object3D = new Line(geometry, new LineBasicMaterial() { Color = new Color().Random() }, type); object3D.Position.X = Mat.Random() * 400 - 200; object3D.Position.Y = Mat.Random() * 400 - 200; object3D.Position.Z = Mat.Random() * 400 - 200; object3D.Rotation.X = Mat.Random() * 2 * (float)Math.PI; object3D.Rotation.Y = Mat.Random() * 2 * (float)Math.PI; object3D.Rotation.Z = Mat.Random() * 2 * (float)Math.PI; object3D.Scale.X = Mat.Random() + 0.5f; object3D.Scale.Y = Mat.Random() + 0.5f; object3D.Scale.Z = Mat.Random() + 0.5f; parentTransform.Add(object3D); } scene.Add(parentTransform); raycaster = new Raycaster(); raycaster.LinePrecision = 3; renderer.SetClearColor((Color)colorConvertor.ConvertFromString("#f0f0f0")); }
/// <summary> /// /// </summary> private Object3D Parse(string text) { // v float float float var vertex_pattern = @"v( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)"; // vn float float float var normal_pattern = @"vn( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)"; // vt float float var uv_pattern = @"vt( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)"; // f vertex vertex vertex ... var face_pattern1 = @"f( +-?\d+)( +-?\d+)( +-?\d+)( +-?\d+)?"; // f vertex/uv vertex/uv vertex/uv ... var face_pattern2 = @"f( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))?"; // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ... var face_pattern3 = @"f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?"; // f vertex//normal vertex//normal vertex//normal ... var face_pattern4 = @"f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?"; var lines = text.Split('\n'); for (var i = 0; i < lines.Length; i++) { var line = lines[i]; line = line.Trim(); if (line.Length == 0 || line[0] == '#') { continue; } { var rgx = new Regex(vertex_pattern, RegexOptions.IgnoreCase); var matches = rgx.Matches(line); foreach (Match match in matches) { this._vertices.AddRange(new [] { floatParse(match.Groups[1].Value), floatParse(match.Groups[2].Value), floatParse(match.Groups[3].Value) }); } if (matches.Count > 0) { continue; } } { var rgx = new Regex(normal_pattern, RegexOptions.IgnoreCase); var matches = rgx.Matches(line); foreach (Match match in matches) { this._normals.AddRange(new[] { floatParse(match.Groups[1].Value), floatParse(match.Groups[2].Value), floatParse(match.Groups[3].Value) }); } if (matches.Count > 0) { continue; } } { var rgx = new Regex(uv_pattern, RegexOptions.IgnoreCase); var matches = rgx.Matches(line); foreach (Match match in matches) { this._uvs.AddRange(new[] { floatParse(match.Groups[1].Value), floatParse(match.Groups[2].Value) }); } if (matches.Count > 0) { continue; } } { var rgx = new Regex(face_pattern1, RegexOptions.IgnoreCase); var matches = rgx.Matches(line); foreach (Match match in matches) { addFace( intParse(match.Groups[1].Value), intParse(match.Groups[2].Value), intParse(match.Groups[3].Value), intParse(match.Groups[4].Value), null, null, null, null, null, null, null, null); } if (matches.Count > 0) { continue; } } { var rgx = new Regex(face_pattern2, RegexOptions.IgnoreCase); var matches = rgx.Matches(line); foreach (Match match in matches) { addFace( intParse(match.Groups[2].Value), intParse(match.Groups[5].Value), intParse(match.Groups[8].Value), intParse(match.Groups[11].Value), intParse(match.Groups[3].Value), intParse(match.Groups[6].Value), intParse(match.Groups[9].Value), intParse(match.Groups[12].Value), null, null, null, null); } if (matches.Count > 0) { continue; } } { var rgx = new Regex(face_pattern3, RegexOptions.IgnoreCase); var matches = rgx.Matches(line); foreach (Match match in matches) { addFace( intParse(match.Groups[2].Value), intParse(match.Groups[6].Value), intParse(match.Groups[10].Value), intParse(match.Groups[14].Value), intParse(match.Groups[3].Value), intParse(match.Groups[7].Value), intParse(match.Groups[11].Value), intParse(match.Groups[15].Value), intParse(match.Groups[4].Value), intParse(match.Groups[8].Value), intParse(match.Groups[12].Value), intParse(match.Groups[16].Value)); } if (matches.Count > 0) { continue; } } { var rgx = new Regex(face_pattern4, RegexOptions.IgnoreCase); var matches = rgx.Matches(line); foreach (Match match in matches) { addFace( intParse(match.Groups[2].Value), intParse(match.Groups[5].Value), intParse(match.Groups[8].Value), intParse(match.Groups[11].Value), null, null, null, null, intParse(match.Groups[3].Value), intParse(match.Groups[6].Value), intParse(match.Groups[9].Value), intParse(match.Groups[12].Value)); } if (matches.Count > 0) { continue; } } if (line.Contains("o ")) { this._geometry = new Geometry(); this._material = new Material(); this._object = new Objekt { name = line.Substring(2, line.Length - 2).Trim(), Geometry = this._geometry, Material = this._material }; this._objects.Add(this._object); continue; } if (line.Contains("g ")) { // group continue; } if (line.Contains("usemtl ")) { // material this._material.name = line.Substring(7, line.Length - 7).Trim(); continue; } if (line.Contains("mtllib ")) { // mtl file continue; } if (line.Contains("s ")) { // // smooth shading continue; } Trace.TraceInformation("OBJLoader: Unhandled line " + line); } var container = new Object3D(); for (var i = 0; i < this._objects.Count; i++) { var obj = this._objects[i]; var geom = obj.Geometry; var buffergeometry = new BufferGeometry(); buffergeometry.AddAttribute("position", new BufferAttribute <float>(geom.Vertices.ToArray(), 3)); if (geom.Normals.Count > 0) { buffergeometry.AddAttribute("normal", new BufferAttribute <float>(geom.Normals.ToArray(), 3)); } if (geom.Uvs.Count > 0) { buffergeometry.AddAttribute("uv", new BufferAttribute <float>(geom.Uvs.ToArray(), 2)); } var mat = new MeshLambertMaterial(); mat.Name = obj.Material.name; var mesh = new Mesh(buffergeometry, mat); mesh.Name = obj.name; container.Add(mesh); } return(container); }
public static Object3D Parse(Renderer renderer, string path, Action <string> mtllibCallback = null) { ObjMtlLoader.renderer = renderer; var text = File.ReadAllText(path); var vector = new Func <string, string, string, Vector3>((x, y, z) => { var vx = Convert.ToSingle(x); var vy = Convert.ToSingle(y); var vz = Convert.ToSingle(z); return(new Vector3(vx, vy, vz)); }); var uv = new Func <string, string, Vector2>((u, v) => { var vu = Convert.ToSingle(u); var vv = Convert.ToSingle(v); return(new Vector2(vu, vv)); }); var parseVertexIndex = new Func <string, int>((indexString) => { var index = Convert.ToInt32(indexString); return(index >= 0 ? index - 1 : index + vertexIndicies.Count); }); var parseNormalIndex = new Func <string, int>((indexString) => { var index = Convert.ToInt32(indexString); return(index >= 0 ? index - 1 : index + normals.Count); }); var parseUVIndex = new Func <string, int>((indexString) => { var index = Convert.ToInt32(indexString); return(index >= 0 ? index - 1 : index + uvs2.Count); }); var add_face = new Action <string, string, string, List <string> >((a, b, c, normals_inds) => { if (normals_inds == null) { geometry.faces.Add(new Face3( vertexIndicies[parseVertexIndex(a)] - 1, vertexIndicies[parseVertexIndex(b)] - 1, vertexIndicies[parseVertexIndex(c)] - 1 )); } else { geometry.faces.Add(new Face3( vertexIndicies[parseVertexIndex(a)] - 1, vertexIndicies[parseVertexIndex(b)] - 1, vertexIndicies[parseVertexIndex(c)] - 1, normals[parseNormalIndex(normals_inds[0])], normals[parseNormalIndex(normals_inds[1])], normals[parseNormalIndex(normals_inds[2])])); } }); var add_uvs = new Action <string, string, string>((a, b, c) => { geometry.faceVertexUvs[0].Add(new UVFaceSet(uvs2[parseUVIndex(a)], uvs2[parseUVIndex(b)], uvs2[parseUVIndex(c)])); }); var handle_face_line = new Action <List <string>, List <string>, List <string> >((faces, uvs, normals_inds) => { if (faces.Count == 3) { add_face(faces[0], faces[1], faces[2], normals_inds); if (uvs != null && uvs.Count > 0) { add_uvs(uvs[0], uvs[1], uvs[2]); } } else { if (normals_inds != null && normals_inds.Count > 0) { add_face(faces[0], faces[1], faces[3], new List <string>() { normals_inds[0], normals_inds[1], normals_inds[3] }); add_face(faces[1], faces[2], faces[3], new List <string>() { normals_inds[1], normals_inds[2], normals_inds[3] }); } else { add_face(faces[0], faces[1], faces[3], null); add_face(faces[1], faces[2], faces[3], null); } if (uvs != null && uvs.Count > 0) { add_uvs(uvs[0], uvs[1], uvs[3]); add_uvs(uvs[1], uvs[2], uvs[3]); } } }); var o = new Object3D(); var lines = text.Split('\n'); // create mesh if no objects in text if (lines.Where(l => l.StartsWith("o")).Count() == 0) { geometry = new Geometry(); material = new MeshBasicMaterial(renderer); mesh = new Mesh(geometry, material); o.Add(mesh); } vertexIndicies = new List <int>(); normals = new List <Vector3>(); uvs2 = new List <Vector2>(); // fixes //text = text.Replace("\r\n",string.Empty); // handles line continuations \ foreach (var l in lines) { if (l.Length == 0 || l[0] == '#') { continue; } var line = l.Trim(); var result = line.Split(' ', '/'); if (vertex_pattern.IsMatch(line)) { // ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"] geometry.vertices.Add( vector( result[1], result[2], result[3] ) ); vertexIndicies.Add(geometry.vertices.Count); } else if (normal_pattern.IsMatch(line)) { // ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"] normals.Add(vector(result[1], result[2], result[3])); } else if (uv_pattern.IsMatch(line)) { // ["vt 0.1 0.2", "0.1", "0.2"] uvs2.Add( uv( result[1], result[2] ) ); } else if (face_pattern1.IsMatch(line)) { // ["f 1 2 3", "1", "2", "3", undefined]WDEAADEAWAAAADD if (result.Length == 4) { handle_face_line(new List <string>() { result[1], result[2], result[3] }, null, null); } else { handle_face_line(new List <string>() { result[1], result[2], result[3], result[4] }, null, null); } } else if (face_pattern2.IsMatch(line)) { // ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined] if (result.Length == 7) { handle_face_line( new List <string>() { result[1], result[3], result[5] }, //faces new List <string>() { result[2], result[4], result[6] }, //uv null ); } else { handle_face_line( new List <string>() { result[1], result[3], result[5], result[7] }, //faces new List <string>() { result[2], result[4], result[6], result[8] }, //uv null ); } } else if (face_pattern3.IsMatch(line)) { if (result.Length == 10) { handle_face_line( new List <string>() { result[1], result[4], result[7], }, //faces new List <string>() { result[2], result[5], result[8], }, //uv new List <string>() { result[3], result[6], result[9], } //normal ); } else { // ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined] handle_face_line( new List <string>() { result[1], result[4], result[7], result[10] }, //faces new List <string>() { result[2], result[5], result[8], result[11] }, //uv new List <string>() { result[3], result[6], result[9], result[12] } //normal ); } } else if (face_pattern4.IsMatch(line)) { if (result.Length == 10) { // ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined] handle_face_line( new List <string>() { result[1], result[4], result[7] }, //faces null, //uv new List <string>() { result[3], result[6], result[9] } //normal ); } else { // ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined] handle_face_line( new List <string>() { result[1], result[4], result[7], result[10] }, //faces null, //uv new List <string>() { result[3], result[6], result[9], result[12] } //normal ); } } else if (objectTest.IsMatch(line)) { geometry = new Geometry(); material = new MeshBasicMaterial(renderer); mesh = new Mesh(geometry, material); mesh.Name = line.Substring(2).Trim(); o.Add(mesh); } else if (groupTest.IsMatch(line)) { // group } else if (useMTLTest.IsMatch(line)) { // material material = materials[result[1].Trim()]; mesh.Material = material; } else if (mtlTest.IsMatch(line)) { // mtl file var objPath = Path.GetDirectoryName(path); var fullPath = Path.Combine(objPath, result[1].Trim()); ParseMaterials(fullPath); } else if (smoothShadingTest.IsMatch(line)) { // smooth shading } else { throw new NotSupportedException(line); } } var children = o.Children; foreach (var c in o.Children) { var geometry = c.geometry; geometry.ComputeNormals(); geometry.ComputeBoundingSphere(); } return(o); }