// a helper to show the world-axis-aligned bounding box for an object public static BoundingBoxHelper Create(Renderer renderer, Object3D o, Color? color = null) { var c = color.HasValue ? color.Value : new Color(0x888888); var geo = new BoxGeometry(1, 1, 1); var mat = new MeshBasicMaterial(renderer) { Diffuse = c, UseWireframe = true }; var boundingBoxHelper = new BoundingBoxHelper(geo, mat); boundingBoxHelper.o = o; boundingBoxHelper.box = Box3.Empty; return boundingBoxHelper; }
private MeshBasicMaterial CreateMaterial(Renderer renderer, JToken materialJson, string texturePath = null) { dynamic material = new MeshLambertMaterial(renderer); var shadingData = materialJson["shading"]; if (shadingData != null) { var shading = shadingData.Value<string>().ToLower(); if (shading == "phong") throw new NotImplementedException(); else if (shading == "basic") material = new MeshBasicMaterial(renderer); } material.DiffuseColor = new Color(0xeeeeee); //material.Opacity = 1; material.UseWireframe = false; var blendingData = materialJson["blending"]; if (blendingData != null) { BlendMode mode; switch(blendingData.Value<string>()) { case "NormalBlending": mode = BlendMode.Normal; break; default: throw new NotSupportedException(); } material.Blending = mode; } var transparentData = materialJson["transparent"]; if (transparentData != null) material.IsTransparent = transparentData.Value<bool>(); var depthTestData = materialJson["depthTest"]; if (depthTestData != null) material.ShouldDepthTest = depthTestData.Value<bool>(); var depthWriteData = materialJson["depthWrite"]; if (depthWriteData != null) material.ShouldDepthWrite = depthWriteData.Value<bool>(); var isVisibleData = materialJson["visible"]; if (isVisibleData != null) material.isVisible = isVisibleData.Value<bool>(); var isFlipSidedData = materialJson["flipSided"]; if (isFlipSidedData != null) material.side = SideMode.Back; var isDoubleSidedData = materialJson["doubleSided"]; if (isFlipSidedData != null) material.side = SideMode.Double; var useWireframeData = materialJson["wireframe"]; if (useWireframeData != null) material.useWireframe = useWireframeData.Value<bool>(); var vertexColorsData = materialJson["vertexColors"]; if (vertexColorsData != null) { if (vertexColorsData.Value<string>() == "face") material.VertexColors = VertexColorMode.Face; else material.VertexColors = VertexColorMode.Vertex; } #region colors var colorDiffuseData = materialJson["colorDiffuse"]; if (colorDiffuseData != null) { var rgb = colorDiffuseData.Values<float>().ToArray(); material.DiffuseColor = new Color(rgb[0], rgb[1], rgb[2]); } else { var debugColorData = materialJson["DbgColor"]; if (debugColorData != null) { material.DiffuseColor = new Color(debugColorData.Value<uint>()); } } var colorSpecularData = materialJson["colorSpecular"]; if (material is MeshPhongMaterial && colorSpecularData != null) { var rgb = colorSpecularData.Values<float>().ToArray(); material.Specular = new Color(rgb[0], rgb[1], rgb[2]); } var ambientData = materialJson["colorAmbient"]; if (ambientData != null) { var rgb = ambientData.Values<float>().ToArray(); material.Ambient = new Color(rgb[0], rgb[1], rgb[2]); } var emissiveData = materialJson["colorEmissive"]; if (emissiveData != null) { var rgb = emissiveData.Values<float>().ToArray(); material.Emissive = new Color(rgb[0], rgb[1], rgb[2]); } #endregion #region modifiers // TODO is opactiy needed? //if (transparentData != null) //{ // material.opacity = transparentData.Value<float>(); //} var shininessData = materialJson["shininess"]; if (shininessData != null) material.shininess = shininessData.Value<float>(); #endregion #region textures var mapDiffuseData = materialJson["mapDiffuse"]; if(mapDiffuseData != null && texturePath != null) { var d = materialJson["mapDiffuse"].Value<string>(); var r = materialJson["mapDiffuseRepeat"]; var o = materialJson["mapDiffuseOffset"]; var wrapData = materialJson["mapDiffuseWrap"]; WrapMode wrapS; switch(wrapData[0].Value<string>()) { case "repeat": wrapS = WrapMode.Repeat;break; default: throw new NotSupportedException(); } WrapMode wrapT; switch (wrapData[1].Value<string>()) { case "repeat": wrapT = WrapMode.Repeat; break; default: throw new NotSupportedException(); } var a = materialJson["mapDiffuseAnisotropy"]; CreateTexture(texturePath, materialJson, "map", d, null, null, wrapS, wrapT, null); } var mapLightData = materialJson["mapLight"]; if(mapLightData != null && texturePath != null) { var d = materialJson["mapLight"]; var r = materialJson["mapLightRepeat"]; var o = materialJson["mapLightOffset"]; var w = materialJson["mapLightWrap"]; var a = materialJson["mapLightAnisotropy"]; throw new NotImplementedException();//CreateTexture( mpars, "lightMap", d,r, o, w, a); } var mapBumpData = materialJson["mapBump"]; if(mapBumpData != null && texturePath != null) { var d = materialJson["mapBump"]; var r = materialJson["mapBumpRepeat"]; var o = materialJson["mapBumpOffset"]; var w = materialJson["mapBumpWrap"]; var a = materialJson["mapBumpAnisotropy"]; throw new NotImplementedException();//CreateTexture( mpars, "bumpMap", d,r, o, w, a); } var mapNormalData = materialJson["mapNormal"]; if(mapNormalData != null && texturePath != null) { var d = materialJson["mapNormal"]; var r = materialJson["mapNormalRepeat"]; var o = materialJson["mapNormalOffset"]; var w = materialJson["mapNormalWrap"]; var a = materialJson["mapNormalAnisotropy"]; throw new NotImplementedException();//CreateTexture( mpars, "normalMap", d,r, o, w, a); } var mapSpecularData = materialJson["mapSpecular"]; if(mapSpecularData != null && texturePath != null) { var d = materialJson["mapSpecular"]; var r = materialJson["mapSpecularRepeat"]; var o = materialJson["mapSpecularOffset"]; var w = materialJson["mapSpecularWrap"]; var a = materialJson["mapSpecularAnisotropy"]; throw new NotImplementedException();//CreateTexture( mpars, "specularMap", d,r, o, w, a); } var mapAlphaData = materialJson["mapAlpha"]; if(mapAlphaData != null && texturePath != null) { var d = materialJson["mapAlpha"]; var r = materialJson["mapAlphaRepeat"]; var o = materialJson["mapAlphaOffset"]; var w = materialJson["mapAlphaWrap"]; var a = materialJson["mapAlphaAnisotropy"]; throw new NotImplementedException();//CreateTexture( mpars, "alphaMap", d,r, o, w, a); } #endregion var mapBumpScaleData = materialJson["mapBumpScale"]; if(mapBumpScaleData != null) material.bumpScale = mapBumpScaleData.Value<float>(); if(mapNormalData != null) { throw new NotImplementedException(); } return material; }
private static Mesh CreateCube(Renderer renderer, Scene scene, string texturesPath, MeshBasicMaterial material) { var cube = new Mesh(new SphereGeometry(1, 50, 50), material); return cube; }
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; }
private BoundingBoxHelper(Geometry geometry, MeshBasicMaterial material) : base(geometry, material) { }
private static void Init() { camera = new PerspectiveCamera(renderer, 30, 1, 10000 ) { Position = new Vector3(0,0,100) }; cameraRTT = new OrthographicCamera(renderer, -10000, 10000 ) { Position= new Vector3(0,0,100) }; scene = new Scene(); sceneRTT = new Scene(); sceneScreen = new Scene(); var light = new DirectionalLight( Color.White ) { Position = Vector3.UnitZ.Normalized() }; sceneRTT.Add( light ); light = new DirectionalLight(new Color(0xffaaaa)) { Position = Vector3.UnitNegativeZ.Normalized(), Intensity = 1.5f }; sceneRTT.Add( light ); rtTexture = new RenderTarget(renderer.Width, renderer.Height) { MinFilter = TextureMinFilter.Linear, MagFilter = TextureMagFilter.Nearest, Format = Three.Net.Renderers.PixelFormat.RGB }; var vertexShaderSource = @" varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }"; var fragment_shader_screenSource = @" varying vec2 vUv; uniform sampler2D tDiffuse; void main() { gl_FragColor = texture2D( tDiffuse, vUv ); }"; var fragment_shader_pass_1Source = @" varying vec2 vUv; uniform float time; void main() { float r = vUv.x; if( vUv.y < 0.5 ) r = 0.0; float g = vUv.y; if( vUv.x < 0.5 ) g = 0.0; gl_FragColor = vec4( r, g, time, 1.0 ); }"; material = new CustomShaderMaterial(renderer,vertexShaderSource,fragment_shader_pass_1Source, m => { }); var materialScreen = new CustomShaderMaterial(renderer, vertexShaderSource, fragment_shader_screenSource, m => {}) { ShouldDepthWrite = false }; var plane = new PlaneGeometry( renderer.Width, renderer.Height); var quad = new Mesh( plane, material ) { Position = new Vector3(0,0,-100) }; sceneRTT.Add( quad ); var geometry = new TorusGeometry( 100, 25, 15, 30 ); var mat1 = new MeshPhongMaterial(renderer) { Diffuse = new Color(0x555555), Specular = new Color(0xffaa00), Shininess = 5 }; var mat2 = new MeshPhongMaterial(renderer) { Diffuse = new Color(0x550000), Specular = new Color(0xff2200), Shininess = 5 }; zmesh1 = new Mesh( geometry, mat1 ) { Position = new Vector3( 0, 0, 100 ), Scale = new Vector3( 1.5f, 1.5f, 1.5f ) }; sceneRTT.Add( zmesh1 ); zmesh2 = new Mesh( geometry, mat2 ) { Position = new Vector3( 0, 150, 100 ), Scale = new Vector3( 0.75f, 0.75f, 0.75f) }; sceneRTT.Add( zmesh2 ); quad = new Mesh( plane, materialScreen ){ Position = new Vector3(0,0,-100) }; sceneScreen.Add( quad ); var n = 5; var sphereGeometry = new SphereGeometry( 10, 64, 32 ); var material2 = new MeshBasicMaterial(renderer) { Diffuse = Color.White, DiffuseMap = rtTexture }; for( var j = 0; j < n; j ++ ) { for( var i = 0; i < n; i ++ ) { var mesh = new Mesh(sphereGeometry, material2) { Position = new Vector3( ( i - ( n - 1 ) / 2 ) * 20, ( j - ( n - 1 ) / 2 ) * 20, 0), Rotation = new Euler(0,-Mathf.Pi / 2, 0) }; scene.Add( mesh ); } } renderer.ShouldAutoClear = false; }
public SkinnedMesh(Geometry geometry, MeshBasicMaterial material, bool useVertexTexture):base(geometry, material) { }