package com.akjava.gwt.three.client.java.utils; import static com.google.common.base.Preconditions.checkNotNull; import com.akjava.gwt.lib.client.LogUtils; import com.akjava.gwt.three.client.examples.utils.GeometryUtils; import com.akjava.gwt.three.client.gwt.core.MorphTarget; import com.akjava.gwt.three.client.gwt.loader.JSONLoaderObject; import com.akjava.gwt.three.client.gwt.materials.LineBasicMaterialParameter; import com.akjava.gwt.three.client.js.THREE; import com.akjava.gwt.three.client.js.core.Geometry; import com.akjava.gwt.three.client.js.extras.geometries.BoxGeometry; import com.akjava.gwt.three.client.js.loaders.JSONLoader; import com.akjava.gwt.three.client.js.loaders.JSONLoader.JSONLoadHandler; import com.akjava.gwt.three.client.js.math.Vector3; import com.akjava.gwt.three.client.js.math.Vector4; import com.akjava.gwt.three.client.js.objects.Line; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONValue; public class GWTGeometryUtils { private GWTGeometryUtils(){} /* * from ,to used in vetex.clone by yourselef if it's necessaly */ public final static Geometry createLineGeometry(Vector3 from,Vector3 to){ Geometry lineG = THREE.Geometry(); lineG.vertices().push(from); lineG.vertices().push(to); return lineG; } public final static boolean isSquare(BoxGeometry geometry){ return geometry.getWidth()==geometry.getHeight() && geometry.getHeight()==geometry.getDepth(); } public final static Line createLineMesh(Vector3 from,Vector3 to,int color){ return THREE.Line(GWTGeometryUtils.createLineGeometry(from, to), THREE.LineBasicMaterial(LineBasicMaterialParameter.create().color(color))); } public final static Line createLineMesh(Vector3 from,Vector3 to,int color,double lineWidth){ return THREE.Line(GWTGeometryUtils.createLineGeometry(from, to), THREE.LineBasicMaterial().color(color).linewidth(lineWidth).build()); } public final static Geometry clonePlusWeights(Geometry geo){ Geometry cloned=geo.clone(); for(int i=0;i<geo.getSkinIndices().length();i++){ cloned.getSkinIndices().push(geo.getSkinIndices().get(i).clone()); } for(int i=0;i<geo.getSkinWeight().length();i++){ cloned.getSkinWeight().push(geo.getSkinWeight().get(i).clone()); } return cloned; } public final static Geometry mergeGeometryPlusWeights(Geometry geo1,Geometry geo2){ GeometryUtils.merge(geo1, geo2); for(int i=0;i<geo2.getSkinIndices().length();i++){ geo1.getSkinIndices().push(geo2.getSkinIndices().get(i)); } for(int i=0;i<geo2.getSkinWeight().length();i++){ geo1.getSkinWeight().push(geo2.getSkinWeight().get(i)); } return geo1; } /** * somehow Blender 2.65 Exporter make all zero "skinIndices" & skinWeights,this geometry not sweat for skin * use this for avoid that. * @param geometry * @return */ public final static boolean isValidSkinIndicesAndWeight(Geometry geometry){ if(geometry.getSkinIndices()==null||geometry.getSkinWeight()==null){ return false; }else if(geometry.getSkinIndices().length()==0 || geometry.getSkinWeight().length()==0){ return false; }else if(geometry.getSkinIndices().length()!=geometry.getSkinWeight().length()){ LogUtils.log("isValidSkinIndicesAndWeight():getSkinIndices and getSkinWeight length is difference"); return false; }else{ Vector4 zero=THREE.Vector4(0,0,0,0); boolean allzero=true; for(int i=0;i<geometry.getSkinWeight().length();i++){ Vector4 weight=geometry.getSkinWeight().get(i); if(!weight.equals(zero)){ allzero=false; break; } } if(allzero){ LogUtils.log("isValidSkinIndicesAndWeight():all-zero weight"); return false; } } return true; } /** * Warning center way is different of GeometryUtils.center() * use center * @param vertices */ public static final void centerOfVertices(JsArray<Vector3> vertices){ Vector3 center=getCenter(vertices); for(int i=0;i<vertices.length();i++){ vertices.get(i).subSelf(center); } } //set center for animation public static final void centerOfMorphTargets(Geometry geometry){ JsArray<MorphTarget> mofs=geometry.getMorphTargets(); GWT.log("mofs:"+mofs.length()); for(int i=0;i<mofs.length();i++){ GWT.log("mofs:-docenter"+i); centerOfVertices(mofs.get(i).getVertices()); } } public static final native Vector3 getCenter(JsArray<Vector3> vertices)/*-{ var center = new $wnd.THREE.Vector3(); for ( var i = 0, l = vertices.length; i < l; i ++ ) { center.addSelf(vertices[ i ].position ); } center.divideScalar( vertices.length ); return center; }-*/; private static JSONObject parseJSONGeometry(String text){ JSONValue json=JSONParser.parseStrict(text); JSONObject jsonObject=json.isObject(); if(jsonObject==null){ return null; } boolean hasData=jsonObject.get("data")!=null;//4.* format has this if(hasData){ jsonObject=jsonObject.get("data").isObject(); } return jsonObject; } /** * support version 3 & 4 * @param jsonText * @param handler * @return */ public static final JSONObject loadJsonModel(String jsonText,JSONLoadHandler handler){ checkNotNull(jsonText,"loadJsonModel:json text is null"); checkNotNull( handler,"loadJsonModel:json handler is null"); JSONLoader loader=THREE.JSONLoader(); JSONObject object=parseJSONGeometry(jsonText); if(object==null){ return null; } JSONLoaderObject loaderObject=loader.parse(object.getJavaScriptObject()); handler.loaded(loaderObject.getGeometry(),loaderObject.getMaterials()); return object; } //TODO create return class public static final JSONObject loadJsonModelWithMaterial(String jsonText){ JSONLoader loader=THREE.JSONLoader(); JSONValue lastJsonValue = JSONParser.parseStrict(jsonText); JSONObject object=lastJsonValue.isObject(); if(object==null){ return null; } JavaScriptObject jsobject=loader.parse(object.getJavaScriptObject(), null); JSONObject newobject=new JSONObject(jsobject); return newobject; } }