SOURCE

console 命令行工具 X clear

                    
>
console
/**
 *
 */
/**
 *
 */
var _svg , _json , _Vertexs , _current , _graphic , _faces = [] , _Traingles = [] , _angle = 0 , _r = 0;
var _windowHalfX , _windowHalfY;
var _V = {x:0 , y:0 , z:300} , _L = {x:0 , y:0 , z:0};

function init(){
	d3.json("https://hankuro.sakura.ne.jp/Model_134/model278_134.json", function(error, root) {
		_json = root;
		_svg = d3.select('#svg');
		_graphic = _svg.select('#graphic');
		_current = 0;
		_Vertexs = _json.vertices;
		makeFace(_json.faces);
		_faces.forEach(function(f,i){ _Traingles.push(new Traingle(f,i)) })
		setInterval(onFrame, 100);
		_windowHalfX = 800 / 2;
	    _windowHalfY = 400 / 2;
	    d3.select('#svg')
	    			.on('mousemove',function(){
	    				var mouse = d3.mouse( this ) ;
	    				 var x = (_windowHalfX - mouse[0]) * -1 ;
	    		         var y = _windowHalfY - mouse[1] ;
	    		        _L.x = x * 10 ;
	    		        _L.y = y * 10;
	    		        console.log(_L.x+' '+_L.y)
	    			})
	})
}
function onFrame(){
	var array = [];
	_Traingles.forEach(function(t){
		t.setVrtex();
		t.rotateY(_angle);
		t.scale(10);
		t.translate([0,-30,0]);
		array.push({obj:t , z:t.getZ()})
	});
	array.sort(function (a,b){
           return a.z < b.z ? -1 : a.z > b.z ? 1 : 0;
     });
     array.forEach(function(e,i){e.obj.draw(i);});

	_angle += 0.03;
}
function Vertex(){
	if(arguments.length == 3){
        this.x = arguments[0];
        this.y = arguments[1];
        this.z = arguments[2];
    }else{
        this.x = 0;
        this.y = 0;
        this.z = 0;
    }
    this.fl = 1000;
}
Vertex.prototype = {
		getScrrenPoint : function(){
            var scale_z = this.fl + this.z;
            var scale = this.fl / scale_z;
            var x = this.x * scale;
            var y = this.y * scale;
            return {x:x , y:y , scale:scale};
        },
        set : function(p1,p2,p3){
            this.x = p1;
            this.y = p2;
            this.z = p3;
        },
        copy : function(v){
            this.x = v.x;
            this.y = v.y;
            this.z = v.z;
        }
}
var _Vector = {
		add : function(p1,p2){
	        var rtn = new Object();
	        rtn.x = p1.x + p2.x;
	        rtn.y = p1.y + p2.y;
	        rtn.z = p1.z + p2.z;
	        return rtn;
	    },
	    substrct : function(p1,p2){
	        var rtn = new Object();
	        rtn.x = p1.x - p2.x;
	        rtn.y = p1.y - p2.y;
	        rtn.z = p1.z - p2.z;
	        return rtn;
	    },
	    dot : function(p1,p2){
	        var rtn;
	        rtn = p1.x*p2.x + p1.y*p2.y + p1.z*p2.z;
	        return rtn;
	    },
	    crossproduct : function(p1,p2){
	        var rtn = new Object();
	        rtn.x = p1.y*p2.z - p1.z*p2.y;
	        rtn.y = p1.z*p2.x - p1.x*p2.z;
	        rtn.z = p1.x*p2.y - p1.y*p2.x;
	        return rtn;
	    },
	    normalize : function(p){
	        var magsq = p.x*p.x + p.y*p.y + p.z*p.z;
	        var rtn = {x : 0 , y : 0 , z : 0};
	        if(magsq > 0.0){
	            var oneovaermag = 1.0 / Math.sqrt(magsq);
	            rtn.x = p.x * oneovaermag;
	            rtn.y = p.y * oneovaermag;
	            rtn.z = p.z * oneovaermag;
	        }
	        return rtn;
	    },
	    check : function(p1,p2){
	        return p1.x==p2.x && p1.y==p2.y && p1.z==p2.z;
	    },
	    distance : function(p1,p2){
	        var dx = p1.x - p2.x;
	        var dy = p1.y - p2.y;
	        var dz = p1.z - p2.z;
	        return Math.sqrt(dx*dx + dy*dy + dz*dz);
	    },
	    Multiply : function(p1,p2){
	        var rtn = {};
	        rtn.x = p1.x * p2;
	        rtn.y = p1.y * p2;
	        rtn.z = p1.z * p2;
	        return rtn;
	    }
}
function Traingle(f,i){
	this.face = f;
    this.index = i;
    this.id = '#dorgon'+i;
    var v1 = new Vertex();
    var v2 = new Vertex();
    var v3 = new Vertex();
    this.Vetexs = [v1,v2,v3];
    this.WorkPos = {x:0 , y:0 , z:0};
    this.setVrtex();
    this.Color =f.Color;
    _graphic.append('path')
    			.attr('d',this.getPath())
    			.attr('id','dorgon'+i)
    			.attr('fill','black')
    			.attr('stroke','none')
}
Traingle.prototype = {
		setVrtex : function(){
            this.Vetexs.forEach(function(e,i){
                switch (i){
                    case 0: setFaceToVetex(this.face.a,this.Vetexs[i]); break;
                    case 1: setFaceToVetex(this.face.b,this.Vetexs[i]); break;
                    case 2: setFaceToVetex(this.face.c,this.Vetexs[i]); break;
                }
            }.bind(this));
            function setFaceToVetex(vindex,v){
                var v1 = _Vertexs[vindex*3 + 0];
                var v2 = _Vertexs[vindex*3 + 1];
                var v3 = _Vertexs[vindex*3 + 2];
                v.set(v1,v2,v3);
            }
        },
        rotateY : function(a){
        	var cos = Math.cos(a);
        	var sin = Math.sin(a);
        	var _this = this;
        	this.Vetexs.forEach(function(v){rotateVertex(v)});
        	function rotateVertex(v){
        		_this.WorkPos.x = cos * v.x  - sin * v.z;
        		_this.WorkPos.y = v.y;
        		_this.WorkPos.z =  cos * v.z  + sin * v.x;
        		v.x = _this.WorkPos.x;
        		v.y = _this.WorkPos.y;
        		v.z = _this.WorkPos.z;
        	}
        },
        scale : function(s){
        	this.Vetexs.forEach(function(v){
        		v.x *= s;
        		v.y *= s;
        		v.z *= s;
        	});
        },
        translate : function(t){
        	this.Vetexs.forEach(function(v){
        		v.x += t[0];
        		v.y += t[1];
        		v.z += t[2];
        	});
        },
        getPath : function(){
            var v1 = this.Vetexs[0].getScrrenPoint();
            var v2 = this.Vetexs[1].getScrrenPoint();
            var v3 = this.Vetexs[2].getScrrenPoint();
            return 'M '+v1.x+' '+v1.y+' L '+v2.x+' '+v2.y+' L '+v3.x+' '+v3.y+' Z';
        },
        getZ : function(){
            return Math.min(this.Vetexs[0].z,this.Vetexs[1].z,this.Vetexs[2].z);
        },
        draw : function(i){
            if(this.isFace()){
            	 _graphic.select('#dorgon'+i)
            	 			.attr('visibility','hidden')
            }else{
            	var color = this.getColor();
            	var d = this.getPath();
            	_graphic.select('#dorgon'+i)
            			   .attr('visibility','visible')
            			   .attr('d',d)
            			   .attr('fill',color)
            }
        },
        isFace : function(){
            var N = this.getNormal();
            return _Vector.dot(_V,N) <= 0;
        },
        getColor : function(){
            var kd = 0.6 , ks = 0.2 , ke = 0.5;
            var WHITE = {x:1 , y:1 , z:1};
            var N = this.getNormal();
            var V = _Vector.substrct(this.Vetexs[0],_V);
            V = _Vector.normalize(V);
            var L = _Vector.substrct(this.Vetexs[0],_L);
            L = _Vector.normalize(L);
            var dot = _Vector.dot(L,N);
            var vec1 = _Vector.Multiply(N,dot);
            vec1 = _Vector.Multiply(vec1,2);
            var R = _Vector.substrct(L,vec1);
            vec1 = _Vector.Multiply(N,-1);
            dot = Math.max(_Vector.dot(vec1,L),0);
            vec1 = _Vector.Multiply(_Vector.Multiply(this.Color,dot),kd);
            var vec2 = _Vector.Multiply(R,-1);
            dot = Math.pow(Math.max(_Vector.dot(vec2,V,0)),20);
            vec2 = _Vector.Multiply(WHITE,dot * ks);
            var vec3 = _Vector.Multiply(this.Color,ke);
            var col = _Vector.add(_Vector.add(vec1,vec2),vec3);
            var red = Math.floor(col.x*255);
            var green = Math.floor(col.y*255);
            var blue = Math.floor(col.z*255);
            return 'rgb('+red+','+green+','+blue+')';
        },
        getNormal : function(){
            var v1 = this.Vetexs[0];
            var v2 = this.Vetexs[1];
            var v3 = this.Vetexs[2];
            var e1 = _Vector.substrct(v3,v2);
            var e2 = _Vector.substrct(v1,v3);
            var N = _Vector.crossproduct(e1,e2);
            N = _Vector.normalize(N);
            return N;
        }
}

function Face(a,b,c){
	this.a = a;
	this.b = b;
	this.c = c;
	this.Color = {x:0 , y:0 , z:0};
}
Face.prototype.setHexColor = function(hex){
	 hex = Math.floor( hex );
     this.Color.x = (hex >> 16 & 255)/255 ;
     this.Color.y = (hex >> 8 & 255)/255 ;
     this.Color.z = (hex & 255)/255 ;
}

function makeFace(faces){
	var offset = 0;
    while (offset < faces.length)
    {
        var type = faces[offset++];
        var isQuad = this.isBitSet(type, 0);
        var hasMaterial = this.isBitSet(type, 1);
        var hasFaceVertexUv = this.isBitSet(type, 3);
        var hasFaceNormal = this.isBitSet(type, 4);
        var hasFaceVertexNormal = this.isBitSet(type, 5);
        var hasFaceColor = this.isBitSet(type, 6);
        var hasFaceVertexColor = this.isBitSet(type, 7);
        if (isQuad != 0)
        {
            var faceA = new Face();
            faceA.a = faces[offset+0];
            faceA.b = faces[offset+1];
            faceA.c = faces[offset+3];
            var faceB = new Face();
            faceB.a = faces[offset+1];
            faceB.b = faces[offset+2];
            faceB.c = faces[offset+3];
            offset += 4;
            if (hasMaterial != 0) offset++;
            if (hasFaceVertexUv != 0)
            {
                for (var i = 0; i < 4; i++) offset++;
            }
            if (hasFaceNormal != 0) offset++;
            if (hasFaceVertexNormal != 0)
            {
                for (var i = 0; i < 4; i++) offset++;
            }
            if (hasFaceColor != 0){
            	offset++;
            }
            if (hasFaceVertexColor != 0)
            {
            	for ( i = 0; i < 4; i ++ ) {
        			var colorIndex = faces[ offset ++ ];
        			var hex = _json.colors[ colorIndex ];
        			if ( i !== 2 ) faceA.setHexColor(hex );
        			if ( i !== 0 ) faceB.setHexColor( hex);
        		}
            }
            _faces.push(faceA);
            _faces.push(faceB);
        }
        else
        {
            var face = new Face();
            face.a = faces[offset++];
            face.b = faces[offset++];
            face.c = faces[offset++];
            if (hasMaterial != 0) offset++;
            if (hasFaceVertexUv != 0)
            {
                for (var i = 0; i < 3; i++) offset++;
            }
            if (hasFaceNormal != 0) offset++;
            if (hasFaceVertexNormal != 0)
            {
                for (var i = 0; i < 3; i++) offset++;
            }
            if (hasFaceColor != 0){
            	offset++;
            }
            if (hasFaceVertexColor != 0)
            {
            	for ( i = 0; i < 3; i ++ ) {
            		var colorIndex = faces[ offset ++ ];
            		var hex = _json.colors[ colorIndex ];
        			face.setHexColor(hex );
        		}
            }
            _faces.push(face);
        }
    }
}
function isBitSet( value, position){
	return value & ( 1 << position );
}
window.onload = function(){init();}
<svg id="svg" width="100%" height="450px" viewBox="0 0 800 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
	<g id="graphic" stroke="none" stroke-width="0.001" fill="#444444" transform="translate(400,250) scale(2.5,-2.5)" >

	</g>
</svg>
body {
  background-color: black;
}
#svg {
	background-color: black;
	margin-top: 30px;
	margin-left: 30px;
}

本项目引用的自定义外部资源