<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JS &#8211; valentin schwind</title>
	<atom:link href="https://vali.de/blog/tag/js/feed/" rel="self" type="application/rss+xml" />
	<link>https://vali.de</link>
	<description>professor of computer graphics</description>
	<lastBuildDate>Sun, 27 Sep 2015 20:25:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>How to bring your 3d models from 3ds max to the browser</title>
		<link>https://vali.de/blog/2011/10/08/bring-mesh-3ds-max-webgl/</link>
					<comments>https://vali.de/blog/2011/10/08/bring-mesh-3ds-max-webgl/#respond</comments>
		
		<dc:creator><![CDATA[valentin]]></dc:creator>
		<pubDate>Sat, 08 Oct 2011 21:24:58 +0000</pubDate>
				<category><![CDATA[3ds Max]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[3d model]]></category>
		<category><![CDATA[3ds max]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[Export]]></category>
		<category><![CDATA[Import]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[MaxScript]]></category>
		<category><![CDATA[Web3D]]></category>
		<category><![CDATA[WebGL]]></category>
		<guid isPermaLink="false">http://www.vali.de/?p=1188</guid>

					<description><![CDATA[This tutorial shows us a simple method to export 3d meshes from 3ds max to an own Javascript file format. We save a 3d-Mesh including textures and UV mapping from 3ds max using MaxScript and load them into a lightweight WebGL-Engine. What you need 3ds max A text editor A WebGL compatible browser (Firefox, Chrome, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>This tutorial shows us a simple method to export 3d meshes from 3ds max to an own Javascript file format. We save a 3d-Mesh including textures and UV mapping from 3ds max using MaxScript and load them into a lightweight WebGL-Engine.</p>
<p><span id="more-1188"></span></p>
<h3>What you need</h3>
<ul>
<li>3ds max</li>
<li>A text editor</li>
<li>A WebGL compatible browser (Firefox, Chrome, &#8230;)</li>
</ul>
<h3>The MaxScript</h3>
<p>Just open a new script file in 3ds max, paste the following code and press Strg-E or Evaluate. A small dialog appears. When you have a standard material with a diffuse texture press the &#8220;Get Diffuse Filename&#8221;-Button to get the name of your texture file. Don&#8217;t forget to copy this texture file into the same directory like the JS- and HTML-File later. To export your selected 3d model press &#8220;Export&#8221; and set your filepath and name.</p>
<p style="text-align: center;"><a class="lightbox" href="http://www.vali.de/wp-content/uploads/teapotin3ds.jpg"><img decoding="async" class="size-medium wp-image-1219 aligncenter" title="teapotin3ds" src="http://www.vali.de/wp-content/uploads/teapotin3ds-210x152.jpg" alt="" width="210" height="152" /></a></p>
<pre class="brush:javascript">	rollout JSExport "js  Export"
	(
		global jsexport_name
		global js_export_captionname
		global js_export_pathname
		global js_export_filetype
		global diffuseName

		group "Export JS Mesh" (
			button filenameBtn "Get Diffuse Filename"
			edittext imagePath ""
			button exportSelected "Export"
		)

		on filenameBtn pressed do
		(
			imagePath.text = filenameFromPath $.material.diffuseMap.filename
		)

		on exportSelected pressed do
		(
			jsexport_name = GetSaveFileName caption:"Save 3D as JS:" types:"JavaScript (*.js)|*.js"
			obj = selection
			if jsexport_name != undefined then(
				tmesh = snapshotAsMesh selection[1]
				out_file = createfile jsexport_name
				num_verts = tmesh.numverts
				num_tverts = tmesh.numtverts
				num_faces = tmesh.numfaces
				format "var triangles = [n" to:out_file
				for f = 1 to num_faces do(
					faceVertIndex = getFace tmesh f
					tVertIndex = getTVFace tmesh f
					for i = 1 to 3 do(
						vpos = getVert tmesh faceVertIndex[i]
						format "%,%,%," vpos.x vpos.y vpos.z to:out_file
						vuvpos = getTVert tmesh tVertIndex[i]
						format "%,%," vuvpos.x vuvpos.y to:out_file
						normals = getNormal tmesh faceVertIndex[i]
						nl = sqrt(normals.x^2 + normals.y^2 + normals.z^2)
						nx = (normals.x/nl) as string
						ny = (normals.y/nl) as string
						nz = (normals.z/nl) as string
						if  nl == 0  then (
							nx = 0
							ny = 0
							nz = 0
						)
						format "%,%,%," nx ny nz to:out_file
					)
					format "n" to:out_file
				)
				format "n];n" to:out_file
				format "var vertCount = %;n" num_verts to:out_file
				format "var faceCount = %;n" num_faces to:out_file
				format "var centre = %;n"  selection[1].pos to:out_file
				format "var diffuseMap = "%";n" imagePath.text  to:out_file
				close out_file
			)
		)
	)createDialog JSExport</pre>
<h3>What you get</h3>
<p>After saving you get a JS-File similar this structure:</p>
<pre class="brush:javascript">var triangles = [
19.6391, -20.3159, 38.8219, 1.85714, 1.98571, -0.957021, 0.218757, -0.190408, 20.2092, -15.2357, 38.8219, 2.0, 1.98571, -0.981749, 0.0, -0.190181, 20.4854, -15.2357, 38.0573, 2.0, 2.0, -0.940499, -1.31962e-007, -0.339798,
...
];
var vertCount = 1598;
var faceCount = 3180;
var centre = [0,0,0];
var diffuseMap = "teapot.jpg";</pre>
<p>The long row in the triangles variable shows only the position, the UVs and the normalized normals of all three vertices in the first triangle of the mesh. The center point is the pivot position in 3ds max.</p>
<h3>The HTML</h3>
<p>For this example you have to load three script files. The first one is your exported mesh. For our WebGL-Example we need the GLMatrix-Utility as secound javascript file. The third file will be our little WebGL example</p>
<pre class="brush:xml">&lt;!DOCTYPE html&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;title&gt;WebGL&lt;/title&gt;
		&lt;script src="teapot.js" type="text/javascript"&gt;
		&lt;script src="http://glmatrix.googlecode.com/files/glMatrix-0.9.5.min.js" type="text/javascript"&gt;
		&lt;script src="webgl.js" type="text/javascript"&gt;
	&lt;/head&gt;
	&lt;body bgcolor="#000" style="margin: auto 0" onload="webGLStart();"&gt;
		&lt;canvas id="GLWindow"&gt;&lt;/canvas&gt;
	&lt;/body&gt;
&lt;/html&gt;</pre>
<h3>The WebGL-Script</h3>
<p>The webgl.js &#8211; File is a small 3d program viewer with an ambient, a directional light and a rotation matrix.</p>
<pre class="brush:javascript">var program;
var mvMatrix = mat4.create();
var pMatrix = mat4.create();
var textureMap;
var VertexBuffer;
var gl;
var rotationMatrix = mat4.create();
var mouseTranslation = [0.0, 0.0, 0.0];
var currentAngle = 0;

function checkGLError(func)
{
	var error = gl.getError();
	if(error != gl.NO_ERROR)
	alert("GL error: " + " " +func + " : " + error);
}

function webGLStart() {
	var canvas = document.getElementById("GLWindow");
	initGL(canvas);
	initShaders();
	initBuffers();
	initTexture();

	gl.clearColor(1.0, 1.0, 1.0, 1.0);
	gl.enable(gl.DEPTH_TEST);

	updateLoop();
}

function initGL(canvas) {
	canvas.width = window.innerWidth;
	canvas.height = window.innerHeight;
	var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
	for (var i = 0; i &lt; names.length; ++i)
	{
		try {
			gl = canvas.getContext(names[i]);
		} catch(e) {}
		if (gl) break;
	}
	if (!gl) alert("Kein WebGL verfuegbar!");	

	gl.viewportWidth = canvas.width;
	gl.viewportHeight = canvas.height;  

}

function initShaders() {

	var vertexShaderSource =
		"attribute vec3 aVertexPosition;n" +
		"attribute vec3 aVertexNormal;n" +
		"attribute vec2 aTextureCoord;n" +

		"uniform mat4 uMVMatrix;n" +
		"uniform mat4 uPMatrix;n" +
		"uniform mat3 uNormalMatrix;n" +
		"uniform vec3 uAmbientColor;n" +
		"uniform vec3 uDirectionalColor;n" +
		"varying vec3 vLightWeighting;n" +
		"varying vec2 vTextureCoord;n" +

		"void main(void) {n" +

			"vec3 ulightDirection = vec3(1.0,1.0,0.0);n" +
			"vec3 transNormal = uNormalMatrix * aVertexNormal;n" +

			"float greyScaleVal = max(dot(transNormal, ulightDirection), 0.0);n" +
			"vec3 uAmbientColor = vec3(0.4,0.4,0.4);n" +
			"vLightWeighting = uAmbientColor + vec3(greyScaleVal,greyScaleVal,greyScaleVal);n" +

			"gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);n" +
			"vTextureCoord = aTextureCoord;n" +
		"}";

	var fragmentShaderSource =
		"#ifdef GL_ESn" +
		"precision highp float;n" +
		"#endifn" +

		"varying vec3 vLightWeighting;n" +
		"varying vec2 vTextureCoord;n" +

		"uniform sampler2D uSampler;n" +

		"void main(void) {	n" +
			"vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));" +
			"gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);" +
		"}";

	var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fragmentShaderSource);
	var vertexShader = loadShader(gl.VERTEX_SHADER, vertexShaderSource);

	program = gl.createProgram();
	gl.attachShader(program, vertexShader);
	gl.attachShader(program, fragmentShader);
	gl.linkProgram(program);

	if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
		alert("Could not initialise program");
	}

	gl.useProgram(program);
	program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
	gl.enableVertexAttribArray(program.vertexPositionAttribute);

	program.vertexNormalAttribute = gl.getAttribLocation(program, "aVertexNormal");
	gl.enableVertexAttribArray(program.vertexNormalAttribute);

	program.textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
	gl.enableVertexAttribArray(program.textureCoordAttribute);

	program.pMatrixUniform = gl.getUniformLocation(program, "uPMatrix");
	program.mvMatrixUniform = gl.getUniformLocation(program, "uMVMatrix");
	program.nMatrixUniform = gl.getUniformLocation(program, "uNormalMatrix");
	program.samplerUniform = gl.getUniformLocation(program, "uSampler");
    program.useLightingUniform = gl.getUniformLocation(program, "uUseLighting");
	program.ambientColorUniform = gl.getUniformLocation(program, "uAmbientColor");
	program.lightingDirectionUniform = gl.getUniformLocation(program, "uLightingDirection");
	program.directionalColorUniform = gl.getUniformLocation(program, "uDirectionalColor");
}

function loadShader(shaderType, source) {
	var shader = gl.createShader(shaderType);
	if (!shader)
		return null;
	gl.shaderSource(shader, source);
	gl.compileShader(shader);

	if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)){
		alert(gl.getHeaderInfoLog(shader));
		return null;
	}
	return shader;
}

function handleLoadedTexture(texture)
{
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.bindTexture(gl.TEXTURE_2D, null);
}

function initBuffers() {
	VertexBuffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, VertexBuffer);
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangles), gl.STATIC_DRAW);
	VertexBuffer.numItems = faceCount * 3;
}

function initTexture()
{
	textureMap = gl.createTexture();
	textureMap.image = new Image();
	textureMap.image.onload = function () {
		handleLoadedTexture(textureMap);
	}

	textureMap.image.src = diffuseMap;
}

function updateLoop() {
	requestAnimFrame(updateLoop);
	drawScene();
}

window.requestAnimFrame = (function() {
	return window.requestAnimationFrame ||
         window.webkitRequestAnimationFrame ||
         window.mozRequestAnimationFrame ||
         window.oRequestAnimationFrame ||
         window.msRequestAnimationFrame ||
         function( callback, element) {
           window.setTimeout(callback, 1000/60);
         };
})();

function drawScene() {
	gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
	gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

	mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);

	mat4.identity(mvMatrix);
	mat4.translate(mvMatrix, [-centre[0],-centre[1],-centre[2]]);

	mat4.translate(mvMatrix, [0.0,0.0,-3.0]);
	mat4.translate(mvMatrix, mouseTranslation);

	currentAngle += 0.2;
	if (currentAngle &gt; 360) currentAngle = 0;
	mat4.rotate(mvMatrix, degToRad(-90), [1, 0, 0]);
	mat4.rotate(mvMatrix, degToRad(currentAngle), [0, 0, 1]);
	setMatrixUniforms();

	gl.bindBuffer(gl.ARRAY_BUFFER, VertexBuffer);
	gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 8*4, 0); // position
	gl.vertexAttribPointer(program.textureCoordAttribute, 2, gl.FLOAT, false, 8*4, 3*4); // texcoord
	gl.vertexAttribPointer(program.vertexNormalAttribute, 3, gl.FLOAT, false, 8*4, 5*4); // normals

	gl.activeTexture(gl.TEXTURE0);
	gl.bindTexture(gl.TEXTURE_2D, textureMap);
	gl.uniform1i(program.samplerUniform, 0);
	gl.useProgram(program);

	gl.drawArrays(gl.TRIANGLES, 0, VertexBuffer.numItems);
}

function degToRad(degrees) {
    return degrees * Math.PI / 180;
}

function setMatrixUniforms() {
	gl.uniformMatrix4fv(program.pMatrixUniform, false, pMatrix);
	gl.uniformMatrix4fv(program.mvMatrixUniform, false, mvMatrix);

	var normalMatrix = mat3.create();
	mat4.toInverseMat3(mvMatrix, normalMatrix);
	mat3.transpose(normalMatrix);
	gl.uniformMatrix3fv(program.nMatrixUniform, false, normalMatrix);
}</pre>
<h3>View the 3d model</h3>
<p>Now just open your HTML-File in your Browser. To view this 3d example online just <a title="WebGL Example" href="http://vali.de/webgl/webgl.htm" target="_blank">click here</a>. Use your browser to get the source online.</p>
<p>Thanks to Norman Pohl for some background information about WebGL.</p>
<p>Greetz<br />
Vali</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vali.de/blog/2011/10/08/bring-mesh-3ds-max-webgl/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
