DVector<DVector<Face3> > Geometry::separate_objects(DVector<Face3> p_array) { DVector<DVector<Face3> > objects; int len = p_array.size(); DVector<Face3>::Read r = p_array.read(); const Face3 *arrayptr = r.ptr(); DVector<_FaceClassify> fc; fc.resize(len); DVector<_FaceClassify>::Write fcw = fc.write(); _FaceClassify *_fcptr = fcw.ptr(); for (int i = 0; i < len; i++) { _fcptr[i].face = arrayptr[i]; } bool error = _connect_faces(_fcptr, len, -1); if (error) { ERR_FAIL_COND_V(error, DVector<DVector<Face3> >()); // invalid geometry } /* group connected faces in separate objects */ int group = 0; for (int i = 0; i < len; i++) { if (!_fcptr[i].valid) continue; if (_group_face(_fcptr, len, i, group)) { group++; } } /* group connected faces in separate objects */ for (int i = 0; i < len; i++) { _fcptr[i].face = arrayptr[i]; } if (group >= 0) { objects.resize(group); DVector<DVector<Face3> >::Write obw = objects.write(); DVector<Face3> *group_faces = obw.ptr(); for (int i = 0; i < len; i++) { if (!_fcptr[i].valid) continue; if (_fcptr[i].group >= 0 && _fcptr[i].group < group) { group_faces[_fcptr[i].group].push_back(_fcptr[i].face); } } } return objects; }
RID VisualServer::_make_test_cube() { DVector<Vector3> vertices; DVector<Vector3> normals; DVector<float> tangents; DVector<Vector3> uvs; int vtx_idx=0; #define ADD_VTX(m_idx);\ vertices.push_back( face_points[m_idx] );\ normals.push_back( normal_points[m_idx] );\ tangents.push_back( normal_points[m_idx][1] );\ tangents.push_back( normal_points[m_idx][2] );\ tangents.push_back( normal_points[m_idx][0] );\ tangents.push_back( 1.0 );\ uvs.push_back( Vector3(uv_points[m_idx*2+0],uv_points[m_idx*2+1],0) );\ vtx_idx++;\ for (int i=0;i<6;i++) { Vector3 face_points[4]; Vector3 normal_points[4]; float uv_points[8]={0,0,0,1,1,1,1,0}; for (int j=0;j<4;j++) { float v[3]; v[0]=1.0; v[1]=1-2*((j>>1)&1); v[2]=v[1]*(1-2*(j&1)); for (int k=0;k<3;k++) { if (i<3) face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1); else face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); } normal_points[j]=Vector3(); normal_points[j][i%3]=(i>=3?-1:1); } //tri 1 ADD_VTX(0); ADD_VTX(1); ADD_VTX(2); //tri 2 ADD_VTX(2); ADD_VTX(3); ADD_VTX(0); } RID test_cube = mesh_create(); Array d; d.resize(VS::ARRAY_MAX); d[VisualServer::ARRAY_NORMAL]= normals ; d[VisualServer::ARRAY_TANGENT]= tangents ; d[VisualServer::ARRAY_TEX_UV]= uvs ; d[VisualServer::ARRAY_VERTEX]= vertices ; DVector<int> indices; indices.resize(vertices.size()); for(int i=0;i<vertices.size();i++) indices.set(i,i); d[VisualServer::ARRAY_INDEX]=indices; mesh_add_surface( test_cube, PRIMITIVE_TRIANGLES,d ); RID material = fixed_material_create(); //material_set_flag(material, MATERIAL_FLAG_BILLBOARD_TOGGLE,true); fixed_material_set_texture( material, FIXED_MATERIAL_PARAM_DIFFUSE, get_test_texture() ); fixed_material_set_param( material, FIXED_MATERIAL_PARAM_SPECULAR_EXP, 70 ); fixed_material_set_param( material, FIXED_MATERIAL_PARAM_EMISSION, Vector3(0.2,0.2,0.2) ); fixed_material_set_param( material, FIXED_MATERIAL_PARAM_DIFFUSE, Color(1, 1, 1) ); fixed_material_set_param( material, FIXED_MATERIAL_PARAM_SPECULAR, Color(1,1,1) ); mesh_surface_set_material(test_cube, 0, material ); return test_cube; }
bool NavigationPolygonEditor::forward_input_event(const InputEvent& p_event) { if (!node) return false; if (node->get_navigation_polygon().is_null()) { if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { create_nav->set_text("No NavigationPolygon resource on this node.\nCreate and assign one?"); create_nav->popup_centered_minsize(); } return (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1);; } switch(p_event.type) { case InputEvent::MOUSE_BUTTON: { const InputEventMouseButton &mb=p_event.mouse_button; Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); Vector2 gpoint = Point2(mb.x,mb.y); Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); cpoint=canvas_item_editor->snap_point(cpoint); cpoint = node->get_global_transform().affine_inverse().xform(cpoint); //first check if a point is to be added (segment split) real_t grab_treshold=EDITOR_DEF("poly_editor/point_grab_radius",8); switch(mode) { case MODE_CREATE: { if (mb.button_index==BUTTON_LEFT && mb.pressed) { if (!wip_active) { wip.clear(); wip.push_back( cpoint ); wip_active=true; edited_point_pos=cpoint; edited_outline=-1; canvas_item_editor->get_viewport_control()->update(); edited_point=1; return true; } else { if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { //wip closed _wip_close(); return true; } else { wip.push_back( cpoint ); edited_point=wip.size(); canvas_item_editor->get_viewport_control()->update(); return true; //add wip point } } } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { _wip_close(); } } break; case MODE_EDIT: { if (mb.button_index==BUTTON_LEFT) { if (mb.pressed) { if (mb.mod.control) { //search edges int closest_outline=-1; int closest_idx=-1; Vector2 closest_pos; real_t closest_dist=1e10; for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { DVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); int pc=points.size(); DVector<Vector2>::Read poly=points.read(); for(int i=0;i<pc;i++) { Vector2 points[2] ={ xform.xform(poly[i]), xform.xform(poly[(i+1)%pc]) }; Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) continue; //not valid to reuse point real_t d = cp.distance_to(gpoint); if (d<closest_dist && d<grab_treshold) { closest_dist=d; closest_outline=j; closest_pos=cp; closest_idx=i; } } } if (closest_idx>=0) { pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); DVector<Point2> poly = pre_move_edit; poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); edited_point=closest_idx+1; edited_outline=closest_outline; edited_point_pos=xform.affine_inverse().xform(closest_pos); node->get_navigation_polygon()->set_outline(closest_outline,poly); canvas_item_editor->get_viewport_control()->update(); return true; } } else { //look for points to move int closest_outline=-1; int closest_idx=-1; Vector2 closest_pos; real_t closest_dist=1e10; for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { DVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); int pc=points.size(); DVector<Vector2>::Read poly=points.read(); for(int i=0;i<pc;i++) { Vector2 cp =xform.xform(poly[i]); real_t d = cp.distance_to(gpoint); if (d<closest_dist && d<grab_treshold) { closest_dist=d; closest_pos=cp; closest_outline=j; closest_idx=i; } } } if (closest_idx>=0) { pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); edited_point=closest_idx; edited_outline=closest_outline; edited_point_pos=xform.affine_inverse().xform(closest_pos); canvas_item_editor->get_viewport_control()->update(); return true; } } } else { if (edited_point!=-1) { //apply DVector<Vector2> poly = node->get_navigation_polygon()->get_outline(edited_outline); ERR_FAIL_INDEX_V(edited_point,poly.size(),false); poly.set(edited_point,edited_point_pos); undo_redo->create_action(TTR("Edit Poly")); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,poly); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,pre_move_edit); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->commit_action(); edited_point=-1; return true; } } } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { int closest_outline=-1; int closest_idx=-1; Vector2 closest_pos; real_t closest_dist=1e10; for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { DVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); int pc=points.size(); DVector<Vector2>::Read poly=points.read(); for(int i=0;i<pc;i++) { Vector2 cp =xform.xform(poly[i]); real_t d = cp.distance_to(gpoint); if (d<closest_dist && d<grab_treshold) { closest_dist=d; closest_pos=cp; closest_outline=j; closest_idx=i; } } } if (closest_idx>=0) { DVector<Vector2> poly = node->get_navigation_polygon()->get_outline(closest_outline); if (poly.size()>3) { undo_redo->create_action(TTR("Edit Poly (Remove Point)")); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); poly.remove(closest_idx); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->commit_action(); } else { undo_redo->create_action(TTR("Remove Poly And Point")); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"add_outline_at_index",poly,closest_outline); poly.remove(closest_idx); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"remove_outline",closest_outline); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->commit_action(); } return true; } } } break; } } break; case InputEvent::MOUSE_MOTION: { const InputEventMouseMotion &mm=p_event.mouse_motion; if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { Vector2 gpoint = Point2(mm.x,mm.y); Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); cpoint=canvas_item_editor->snap_point(cpoint); edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); canvas_item_editor->get_viewport_control()->update(); } } break; } return false; }
void FileDialog::_action_pressed() { if (mode==MODE_OPEN_FILES) { TreeItem *ti=tree->get_next_selected(NULL); String fbase=dir_access->get_current_dir(); DVector<String> files; while(ti) { files.push_back( fbase.plus_file(ti->get_text(0)) ); ti=tree->get_next_selected(ti); } if (files.size()) { emit_signal("files_selected",files); hide(); } return; } String f=dir_access->get_current_dir().plus_file(file->get_text()); if (mode==MODE_OPEN_FILE && dir_access->file_exists(f)) { emit_signal("file_selected",f); hide(); } if (mode==MODE_OPEN_DIR) { String path=dir_access->get_current_dir(); /*if (tree->get_selected()) { Dictionary d = tree->get_selected()->get_metadata(0); if (d["dir"]) { path=path+"/"+String(d["name"]); } }*/ path=path.replace("\\","/"); emit_signal("dir_selected",path); hide(); } if (mode==MODE_SAVE_FILE) { bool valid=false; if (filter->get_selected()==filter->get_item_count()-1) { valid=true; //match none } else if (filters.size()>1 && filter->get_selected()==0) { // match all filters for (int i=0;i<filters.size();i++) { String flt=filters[i].get_slice(";",0); for (int j=0;j<flt.get_slice_count(",");j++) { String str = flt.get_slice(",",j).strip_edges(); if (f.match(str)) { valid=true; break; } } if (valid) break; } } else { int idx=filter->get_selected(); if (filters.size()>1) idx--; if (idx>=0 && idx<filters.size()) { String flt=filters[idx].get_slice(";",0); int filterSliceCount=flt.get_slice_count(","); for (int j=0;j<filterSliceCount;j++) { String str = (flt.get_slice(",",j).strip_edges()); if (f.match(str)) { valid=true; break; } } if (!valid && filterSliceCount>0) { String str = (flt.get_slice(",",0).strip_edges()); f+=str.substr(1, str.length()-1); file->set_text(f.get_file()); valid=true; } } else { valid=true; } } if (!valid) { exterr->popup_centered_minsize(Size2(250,80)); return; } if (dir_access->file_exists(f)) { confirm_save->set_text("File Exists, Overwrite?"); confirm_save->popup_centered(Size2(200,80)); } else { emit_signal("file_selected",f); hide(); } } }
void PathRemap::load_remaps() { // default remaps first DVector<String> remaps = GlobalConfig::get_singleton()->get("remap/all"); { int rlen = remaps.size(); ERR_FAIL_COND( rlen%2 ); DVector<String>::Read r = remaps.read(); for(int i=0;i<rlen/2;i++) { String from = r[i*2+0]; String to = r[i*2+1]; add_remap(from,to); } } // platform remaps second, so override remaps = GlobalConfig::get_singleton()->get("remap/"+OS::get_singleton()->get_name()); // remaps = Globals::get_singleton()->get("remap/PSP"); { int rlen = remaps.size(); ERR_FAIL_COND( rlen%2 ); DVector<String>::Read r = remaps.read(); for(int i=0;i<rlen/2;i++) { String from = r[i*2+0]; String to = r[i*2+1]; // print_line("add remap: "+from+" -> "+to); add_remap(from,to); } } //locale based remaps if (GlobalConfig::get_singleton()->has("locale/translation_remaps")) { Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps"); List<Variant> rk; remaps.get_key_list(&rk); for(List<Variant>::Element *E=rk.front();E;E=E->next()) { String source = E->get(); StringArray sa = remaps[E->get()]; int sas = sa.size(); StringArray::Read r = sa.read(); for(int i=0;i<sas;i++) { String s = r[i]; int qp = s.find_last(":"); if (qp!=-1) { String path = s.substr(0,qp); String locale = s.substr(qp+1,s.length()); add_remap(source,path,locale); } } } } }
void NavigationPolygon::make_polygons_from_outlines() { List<TriangulatorPoly> in_poly,out_poly; Vector2 outside_point(-1e10,-1e10); for(int i=0; i<outlines.size(); i++) { DVector<Vector2> ol = outlines[i]; int olsize = ol.size(); if (olsize<3) continue; DVector<Vector2>::Read r=ol.read(); for(int j=0; j<olsize; j++) { outside_point.x = MAX( r[j].x, outside_point.x ); outside_point.y = MAX( r[j].y, outside_point.y ); } } outside_point+=Vector2(0.7239784,0.819238); //avoid precision issues for(int i=0; i<outlines.size(); i++) { DVector<Vector2> ol = outlines[i]; int olsize = ol.size(); if (olsize<3) continue; DVector<Vector2>::Read r=ol.read(); int interscount=0; //test if this is an outer outline for(int k=0; k<outlines.size(); k++) { if (i==k) continue; //no self intersect DVector<Vector2> ol2 = outlines[k]; int olsize2 = ol2.size(); if (olsize2<3) continue; DVector<Vector2>::Read r2=ol2.read(); for(int l=0; l<olsize2; l++) { if (Geometry::segment_intersects_segment_2d(r[0],outside_point,r2[l],r2[(l+1)%olsize2],NULL)) { interscount++; } } } bool outer = (interscount%2)==0; TriangulatorPoly tp; tp.Init(olsize); for(int j=0; j<olsize; j++) { tp[j]=r[j]; } if (outer) tp.SetOrientation(TRIANGULATOR_CCW); else { tp.SetOrientation(TRIANGULATOR_CW); tp.SetHole(true); } in_poly.push_back(tp); } TriangulatorPartition tpart; if (tpart.ConvexPartition_HM(&in_poly,&out_poly)==0) { //failed! print_line("convex partition failed!"); return; } polygons.clear(); vertices.resize(0); Map<Vector2,int> points; for(List<TriangulatorPoly>::Element*I = out_poly.front(); I; I=I->next()) { TriangulatorPoly& tp = I->get(); struct Polygon p; for(int i=0; i<tp.GetNumPoints(); i++) { Map<Vector2,int>::Element *E=points.find(tp[i]); if (!E) { E=points.insert(tp[i],vertices.size()); vertices.push_back(tp[i]); } p.indices.push_back(E->get()); } polygons.push_back(p); } emit_signal(CoreStringNames::get_singleton()->changed); }
void Polygon2DEditor::_menu_option(int p_option) { switch(p_option) { case MODE_CREATE: { mode=MODE_CREATE; button_create->set_pressed(true); button_edit->set_pressed(false); } break; case MODE_EDIT: { mode=MODE_EDIT; button_create->set_pressed(false); button_edit->set_pressed(true); } break; case MODE_EDIT_UV: { if (node->get_texture().is_null()) { error->set_text("No texture in this polygon.\nSet a texture to be able to edit UV."); error->popup_centered_minsize(); return; } DVector<Vector2> points = node->get_polygon(); DVector<Vector2> uvs = node->get_uv(); if (uvs.size()!=points.size()) { undo_redo->create_action("Create UV Map"); undo_redo->add_do_method(node,"set_uv",points); undo_redo->add_undo_method(node,"set_uv",uvs); undo_redo->add_do_method(uv_edit_draw,"update"); undo_redo->add_undo_method(uv_edit_draw,"update"); undo_redo->commit_action(); } uv_edit->popup_centered_ratio(0.85); } break; case UVEDIT_POLYGON_TO_UV: { DVector<Vector2> points = node->get_polygon(); if (points.size()==0) break; DVector<Vector2> uvs = node->get_uv(); undo_redo->create_action("Create UV Map"); undo_redo->add_do_method(node,"set_uv",points); undo_redo->add_undo_method(node,"set_uv",uvs); undo_redo->add_do_method(uv_edit_draw,"update"); undo_redo->add_undo_method(uv_edit_draw,"update"); undo_redo->commit_action(); } break; case UVEDIT_UV_TO_POLYGON: { DVector<Vector2> points = node->get_polygon(); DVector<Vector2> uvs = node->get_uv(); if (uvs.size()==0) break; undo_redo->create_action("Create UV Map"); undo_redo->add_do_method(node,"set_polygon",uvs); undo_redo->add_undo_method(node,"set_polygon",points); undo_redo->add_do_method(uv_edit_draw,"update"); undo_redo->add_undo_method(uv_edit_draw,"update"); undo_redo->commit_action(); } break; case UVEDIT_UV_CLEAR: { DVector<Vector2> uvs = node->get_uv(); if (uvs.size()==0) break; undo_redo->create_action("Create UV Map"); undo_redo->add_do_method(node,"set_uv",DVector<Vector2>()); undo_redo->add_undo_method(node,"set_uv",uvs); undo_redo->add_do_method(uv_edit_draw,"update"); undo_redo->add_undo_method(uv_edit_draw,"update"); undo_redo->commit_action(); } break; } }
virtual Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error) { print_line("attempt to call "+String(p_method)); r_error.error=Variant::CallError::CALL_OK; Map<StringName,MethodData >::Element *E=method_map.find(p_method); if (!E) { print_line("no exists"); r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } int ac = E->get().argtypes.size(); if (ac<p_argcount) { print_line("fewargs"); r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument=ac; return Variant(); } if (ac>p_argcount) { print_line("manyargs"); r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument=ac; return Variant(); } for(int i=0;i<p_argcount;i++) { if (!Variant::can_convert(p_args[i]->get_type(),E->get().argtypes[i])) { r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument=i; r_error.expected=E->get().argtypes[i]; } } jvalue *v=NULL; if (p_argcount) { v=(jvalue*)alloca( sizeof(jvalue)*p_argcount ); } for(int i=0;i<p_argcount;i++) { switch(E->get().argtypes[i]) { case Variant::BOOL: { v[i].z=*p_args[i]; } break; case Variant::INT: { v[i].i=*p_args[i]; } break; case Variant::REAL: { v[i].f=*p_args[i]; } break; case Variant::STRING: { String s = *p_args[i]; jstring jStr = env->NewStringUTF(s.utf8().get_data()); v[i].l=jStr; } break; case Variant::STRING_ARRAY: { DVector<String> sarray = *p_args[i]; jobjectArray arr = env->NewObjectArray(sarray.size(),env->FindClass("java/lang/String"),env->NewStringUTF("")); for(int j=0;j<sarray.size();j++) { env->SetObjectArrayElement(arr,j,env->NewStringUTF( sarray[i].utf8().get_data() )); } v[i].l=arr; } break; case Variant::INT_ARRAY: { DVector<int> array = *p_args[i]; jintArray arr = env->NewIntArray(array.size()); DVector<int>::Read r = array.read(); env->SetIntArrayRegion(arr,0,array.size(),r.ptr()); v[i].l=arr; } break; case Variant::REAL_ARRAY: { DVector<float> array = *p_args[i]; jfloatArray arr = env->NewFloatArray(array.size()); DVector<float>::Read r = array.read(); env->SetFloatArrayRegion(arr,0,array.size(),r.ptr()); v[i].l=arr; } break; default: { ERR_FAIL_V(Variant()); } break; } } print_line("calling method!!"); Variant ret; switch(E->get().ret_type) { case Variant::NIL: { print_line("call void"); env->CallVoidMethodA(instance,E->get().method,v); } break; case Variant::BOOL: { ret = env->CallBooleanMethodA(instance,E->get().method,v); print_line("call bool"); } break; case Variant::INT: { ret = env->CallIntMethodA(instance,E->get().method,v); print_line("call int"); } break; case Variant::REAL: { ret = env->CallFloatMethodA(instance,E->get().method,v); } break; case Variant::STRING: { jobject o = env->CallObjectMethodA(instance,E->get().method,v); String singname = env->GetStringUTFChars((jstring)o, NULL ); } break; case Variant::STRING_ARRAY: { jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance,E->get().method,v); int stringCount = env->GetArrayLength(arr); DVector<String> sarr; for (int i=0; i<stringCount; i++) { jstring string = (jstring) env->GetObjectArrayElement(arr, i); const char *rawString = env->GetStringUTFChars(string, 0); sarr.push_back(String(rawString)); } ret=sarr; } break; case Variant::INT_ARRAY: { jintArray arr = (jintArray)env->CallObjectMethodA(instance,E->get().method,v); int fCount = env->GetArrayLength(arr); DVector<int> sarr; sarr.resize(fCount); DVector<int>::Write w = sarr.write(); env->GetIntArrayRegion(arr,0,fCount,w.ptr()); w = DVector<int>::Write(); ret=sarr; } break; case Variant::REAL_ARRAY: { jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance,E->get().method,v); int fCount = env->GetArrayLength(arr); DVector<float> sarr; sarr.resize(fCount); DVector<float>::Write w = sarr.write(); env->GetFloatArrayRegion(arr,0,fCount,w.ptr()); w = DVector<float>::Write(); ret=sarr; } break; default: { print_line("failure.."); ERR_FAIL_V(Variant()); } break; } print_line("success"); return ret; }
void ThetaOperator::forwardEstimation( boost::ptr_vector<MeshContext>& contextStack , FitobCalculator* calc , int& stackIndex , double& timeStamp ){ FITOB_OUT_LEVEL3(verb(),"ThetaOperator::forwardEstimation stackIndex:" << stackIndex << "timeStamp" << timeStamp << " contextStack.size():" << contextStack.size()); MeshContext& actualContext = contextStack[stackIndex]; if (thetaExpression_->isConstantExpression(actualContext) == false){ FITOB_ERROR_EXIT(" ThetaOperator, theta expression is not constant "); } // evaluate the the expression (theta time) and store it thetaTime_ = thetaExpression_->eval(actualContext.minGlobCoord()); // todo: these values now are not taken in consideration, // This might be a future feature, to split up one Theta operator in small theta operators // in case of too large macro time step // 19.09.2010 -> at todays knowledge this is not necessary, this would only make things worse maxThetaTime_ = 10.0; //calc->getXMLConfiguration().get()->getDoubleConfiguration("thetaconfigurations.solver.maxThetaStep.<xmlattr>.value" ); nr_Theta_ = ceil(thetaTime_/maxThetaTime_); const boost::shared_ptr<ModelCollection>& factorModels = calc->getModelCollection(); const boost::shared_ptr<ScriptModel>& scriptModel = calc->getScriptModel(); const OperatorSequence& scriptBody = scriptModel->bodyOpSeq(); const Domain& actDom = actualContext.getDom(); int nrFactors = factorModels->nrFactors(); Domain newDom(actDom); FITOB_OUT_LEVEL3(verb(),"ThetaOperator::forwardEstimation nrFactors:" << factorModels->nrFactors() << " thetaTime:" << thetaTime_ ); for (int factorIndex = 0 ; factorIndex < nrFactors ; factorIndex++) { const FactorModelBase& model = factorModels->getModel(factorIndex); int globalIndex = model.getGlobalIndex(); const DVector& startVal = calc->getStartDomain()->getGradedAxis(globalIndex); // get the points of the normal distribution DVector stdPoints; returnScaledNormalDistribution( actDom.getMaximalLevel() , factorModels->stdFactor(factorIndex) , 1 , stdPoints ); FITOB_OUT_LEVEL3(verb(),"ThetaOperator::forwardEstimation factorIndex:" << factorIndex << " P.size():" << stdPoints.size()); // here we calculate the scaling if (startVal.size() > 1){ for (unsigned int pointI = 0; pointI < stdPoints.size() ; pointI++ ){ double endVal = 0.0; model.forwardEstimation(startVal[pointI] , timeStamp + thetaTime_ , stdPoints[pointI] , actDom.getAverage() , endVal ); if (verb()>3){ std::cout << endVal << ","; } stdPoints[pointI] = endVal; } if (verb()>3) std::cout << std::endl; } else { for (unsigned int pointI = 0; pointI < stdPoints.size() ; pointI++ ){ double endVal = 0.0; model.forwardEstimation(startVal[0] , timeStamp + thetaTime_ , stdPoints[pointI] , actDom.getAverage() , endVal ); if (verb()>3){ std::cout << endVal << ","; } stdPoints[pointI] = endVal; } if (verb()>3) std::cout << std::endl; } //and call forwardEstimation_DiffusionEnlarement int stackIndex_tmp = 0; scriptBody.forwardEstimation_DiffusionEnlarement( contextStack , calc ,stdPoints , globalIndex , stackIndex_tmp , timeStamp ); // sort stdPoints vector - not necessary (even in mean reversion case) // - this is not necessary since we estimate the values from 0 till T and not for dT std::sort( stdPoints.begin(),stdPoints.end() ); // set the axis in the new domain newDom.setAxis(stdPoints,globalIndex); } // add new context, extend contextStack contextStack.push_back(new MeshContext(newDom,timeStamp)); FITOB_OUT_LEVEL3(verb(),"ThetaOperator::forwardEstimation New Domain:" << newDom.toString() ); timeStamp = timeStamp + thetaTime_; stackIndex = stackIndex + 1; }
Variant::operator String() const { switch( type ) { case NIL: return ""; case BOOL: return _data._bool ? "True" : "False"; case INT: return String::num(_data._int); case REAL: return String::num(_data._real); case STRING: return *reinterpret_cast<const String*>(_data._mem); case VECTOR2: return operator Vector2(); case RECT2: return operator Rect2(); case MATRIX32: return operator Matrix32(); case VECTOR3: return operator Vector3(); case PLANE: return operator Plane(); //case QUAT: case _AABB: return operator AABB(); case QUAT: return operator Quat(); case MATRIX3: return operator Matrix3(); case TRANSFORM: return operator Transform(); case NODE_PATH: return operator NodePath(); case INPUT_EVENT: return operator InputEvent(); case COLOR: return String::num( operator Color().r)+","+String::num( operator Color().g)+","+String::num( operator Color().b)+","+String::num( operator Color().a) ; case DICTIONARY: { const Dictionary &d =*reinterpret_cast<const Dictionary*>(_data._mem); //const String *K=NULL; String str; List<Variant> keys; d.get_key_list(&keys); Vector<_VariantStrPair> pairs; for(List<Variant>::Element *E=keys.front();E;E=E->next()) { _VariantStrPair sp; sp.key=String(E->get()); sp.value=d[E->get()]; pairs.push_back(sp); } pairs.sort(); for(int i=0;i<pairs.size();i++) { if (i>0) str+=", "; str+="("+pairs[i].key+":"+pairs[i].value+")"; } return str; } break; case VECTOR3_ARRAY: { DVector<Vector3> vec = operator DVector<Vector3>(); String str; for(int i=0;i<vec.size();i++) { if (i>0) str+=", "; str=str+Variant( vec[i] ); } return str; } break; case STRING_ARRAY: { DVector<String> vec = operator DVector<String>(); String str; for(int i=0;i<vec.size();i++) { if (i>0) str+=", "; str=str+vec[i]; } return str; } break; case INT_ARRAY: { DVector<int> vec = operator DVector<int>(); String str; for(int i=0;i<vec.size();i++) { if (i>0) str+=", "; str=str+itos(vec[i]); } return str; } break; case REAL_ARRAY: { DVector<real_t> vec = operator DVector<real_t>(); String str; for(int i=0;i<vec.size();i++) { if (i>0) str+=", "; str=str+rtos(vec[i]); } return str; } break; case ARRAY: { Array arr = operator Array(); String str; for (int i=0; i<arr.size(); i++) { if (i) str+=", "; str += String(arr[i]); }; return str; } break; case OBJECT: { if (_get_obj().obj) return "["+_get_obj().obj->get_type()+":"+itos(_get_obj().obj->get_instance_ID())+"]"; else return "[Object:null]"; } break; default: { return "["+get_type_name(type)+"]"; } } return ""; }
bool TileMapEditor::forward_input_event(const InputEvent& p_event) { if (!node || !node->get_tileset().is_valid() || !node->is_visible()) return false; Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); Matrix32 xform_inv = xform.affine_inverse(); switch(p_event.type) { case InputEvent::MOUSE_BUTTON: { const InputEventMouseButton &mb=p_event.mouse_button; if (mb.button_index==BUTTON_LEFT) { if (mb.pressed) { if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return false; //drag if (tool==TOOL_NONE) { if (mb.mod.shift) { if (mb.mod.control) tool=TOOL_RECTANGLE_PAINT; else tool=TOOL_LINE_PAINT; selection_active=false; rectangle_begin=over_tile; return true; } if (mb.mod.control) { tool=TOOL_PICKING; _pick_tile(over_tile); return true; } tool=TOOL_PAINTING; } if (tool==TOOL_PAINTING) { int id = get_selected_tile(); if (id!=TileMap::INVALID_CELL) { tool=TOOL_PAINTING; paint_undo.clear(); paint_undo[over_tile]=_get_op_from_cell(over_tile); _set_cell(over_tile, id, flip_h, flip_v, transpose); } } else if (tool==TOOL_PICKING) { _pick_tile(over_tile); } else if (tool==TOOL_SELECTING) { selection_active=true; rectangle_begin=over_tile; } return true; } else { if (tool!=TOOL_NONE) { if (tool==TOOL_PAINTING) { int id=get_selected_tile(); if (id!=TileMap::INVALID_CELL && paint_undo.size()) { undo_redo->create_action(TTR("Paint TileMap")); for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { Point2 p=E->key(); undo_redo->add_do_method(node,"set_cellv",p,id,flip_h,flip_v,transpose); undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); paint_undo.clear(); } } else if (tool==TOOL_LINE_PAINT) { int id=get_selected_tile(); if (id!=TileMap::INVALID_CELL) { undo_redo->create_action("Line Draw"); for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { _set_cell(E->key(), id, flip_h, flip_v, transpose, true); } undo_redo->commit_action(); paint_undo.clear(); canvas_item_editor->update(); } } else if (tool==TOOL_RECTANGLE_PAINT) { int id=get_selected_tile(); if (id!=TileMap::INVALID_CELL) { undo_redo->create_action("Rectangle Paint"); for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { _set_cell(Point2i(j, i), id, flip_h, flip_v, transpose, true); } } undo_redo->commit_action(); canvas_item_editor->update(); } } else if (tool==TOOL_DUPLICATING) { Point2 ofs = over_tile-rectangle.pos; undo_redo->create_action(TTR("Duplicate")); for (List<TileData>::Element *E=copydata.front();E;E=E->next()) { _set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true); } undo_redo->commit_action(); copydata.clear(); canvas_item_editor->update(); } else if (tool==TOOL_SELECTING) { canvas_item_editor->update(); } else if (tool==TOOL_BUCKET) { DVector<Vector2> points = _bucket_fill(over_tile); if (points.size() == 0) return false; Dictionary op; op["id"] = get_selected_tile(); op["flip_h"] = flip_h; op["flip_v"] = flip_v; op["transpose"] = transpose; undo_redo->create_action("Bucket Fill"); undo_redo->add_do_method(this, "_fill_points", points, op); undo_redo->add_undo_method(this, "_erase_points", points); undo_redo->commit_action(); } tool=TOOL_NONE; return true; } } } else if (mb.button_index==BUTTON_RIGHT) { if (mb.pressed) { if (tool==TOOL_SELECTING || selection_active) { tool=TOOL_NONE; selection_active=false; canvas_item_editor->update(); return true; } if (tool==TOOL_DUPLICATING) { tool=TOOL_NONE; copydata.clear(); canvas_item_editor->update(); return true; } if (tool==TOOL_NONE) { paint_undo.clear(); Point2 local = node->world_to_map(xform_inv.xform(Point2(mb.x, mb.y))); if (mb.mod.shift) { if (mb.mod.control) tool=TOOL_RECTANGLE_ERASE; else tool=TOOL_LINE_ERASE; selection_active=false; rectangle_begin=local; } else { tool=TOOL_ERASING; paint_undo[local]=_get_op_from_cell(local); _set_cell(local, TileMap::INVALID_CELL); } return true; } } else { if (tool==TOOL_ERASING || tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) { if (paint_undo.size()) { undo_redo->create_action(TTR("Erase TileMap")); for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { Point2 p=E->key(); undo_redo->add_do_method(node,"set_cellv",p,TileMap::INVALID_CELL,false,false,false); undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); paint_undo.clear(); } if (tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) { canvas_item_editor->update(); } tool=TOOL_NONE; return true; } } } } break; case InputEvent::MOUSE_MOTION: { const InputEventMouseMotion &mm=p_event.mouse_motion; Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x,mm.y))); if (new_over_tile!=over_tile) { over_tile=new_over_tile; canvas_item_editor->update(); } if (tool==TOOL_PAINTING) { int id = get_selected_tile(); if (id!=TileMap::INVALID_CELL) { if (!paint_undo.has(over_tile)) { paint_undo[over_tile]=_get_op_from_cell(over_tile); } _set_cell(over_tile, id, flip_h, flip_v, transpose); return true; } } if (tool==TOOL_SELECTING) { _select(rectangle_begin, over_tile); return true; } if (tool==TOOL_LINE_PAINT || tool==TOOL_LINE_ERASE) { int id = get_selected_tile(); bool erasing = (tool==TOOL_LINE_ERASE); if (erasing && paint_undo.size()) { for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) { _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr); } } paint_undo.clear(); if (id!=TileMap::INVALID_CELL) { Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y); for (int i=0;i<points.size();i++) { paint_undo[points[i]]=_get_op_from_cell(points[i]); if (erasing) _set_cell(points[i], TileMap::INVALID_CELL); } canvas_item_editor->update(); } return true; } if (tool==TOOL_RECTANGLE_PAINT || tool==TOOL_RECTANGLE_ERASE) { _select(rectangle_begin, over_tile); if (tool==TOOL_RECTANGLE_ERASE) { if (paint_undo.size()) { for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) { _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr); } } paint_undo.clear(); for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { Point2i tile = Point2i(j, i); paint_undo[tile]=_get_op_from_cell(tile); _set_cell(tile, TileMap::INVALID_CELL); } } } return true; } if (tool==TOOL_ERASING) { if (!paint_undo.has(over_tile)) { paint_undo[over_tile]=_get_op_from_cell(over_tile); } _set_cell(over_tile, TileMap::INVALID_CELL); return true; } if (tool==TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { _pick_tile(over_tile); return true; } } break; case InputEvent::KEY: { const InputEventKey &k = p_event.key; if (!k.pressed) break; if (k.scancode==KEY_ESCAPE) { if (tool==TOOL_DUPLICATING) copydata.clear(); else if (tool==TOOL_SELECTING || selection_active) selection_active=false; tool=TOOL_NONE; canvas_item_editor->update(); return true; } if (tool!=TOOL_NONE || !mouse_over) return false; if (k.scancode==KEY_DELETE) { _menu_option(OPTION_ERASE_SELECTION); return true; } if (k.mod.command) { if (k.scancode==KEY_F) { search_box->select_all(); search_box->grab_focus(); return true; } if (k.scancode==KEY_B) { tool=TOOL_SELECTING; selection_active=false; canvas_item_editor->update(); return true; } if (k.scancode==KEY_D) { _update_copydata(); if (selection_active) { tool=TOOL_DUPLICATING; canvas_item_editor->update(); return true; } } } else { if (k.scancode==KEY_A) { flip_h=!flip_h; mirror_x->set_pressed(flip_h); canvas_item_editor->update(); return true; } if (k.scancode==KEY_S) { flip_v=!flip_v; mirror_y->set_pressed(flip_v); canvas_item_editor->update(); return true; } } } break; } return false; }
Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<ResourceImportMetadata>& p_from,EditorExportPlatform::ImageCompression p_compr, bool p_external){ ERR_FAIL_COND_V(p_from->get_source_count()==0,ERR_INVALID_PARAMETER); Ref<ResourceImportMetadata> from=p_from; Ref<ImageTexture> texture; Vector<Ref<AtlasTexture> > atlases; bool atlas = from->get_option("atlas"); bool large = from->get_option("large"); int flags=from->get_option("flags"); int format=from->get_option("format"); float quality=from->get_option("quality"); uint32_t tex_flags=0; if (flags&EditorTextureImportPlugin::IMAGE_FLAG_REPEAT) tex_flags|=Texture::FLAG_REPEAT; if (flags&EditorTextureImportPlugin::IMAGE_FLAG_FILTER) tex_flags|=Texture::FLAG_FILTER; if (!(flags&EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS)) tex_flags|=Texture::FLAG_MIPMAPS; if (flags&EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR) tex_flags|=Texture::FLAG_CONVERT_TO_LINEAR; if (flags&EditorTextureImportPlugin::IMAGE_FLAG_USE_ANISOTROPY) tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER; print_line("path: "+p_path+" flags: "+itos(tex_flags)); float shrink=1; if (from->has_option("shrink")) shrink=from->get_option("shrink"); if (large) { ERR_FAIL_COND_V(from->get_source_count()!=1,ERR_INVALID_PARAMETER); String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); int cell_size=from->get_option("large_cell_size"); ERR_FAIL_COND_V(cell_size<128 || cell_size>16384,ERR_CANT_OPEN); EditorProgress pg("ltex","Import Large Texture",3); pg.step("Load Source Image",0); Image img; Error err = ImageLoader::load_image(src_path,&img); if (err) { return err; } pg.step("Slicing",1); Map<Vector2,Image> pieces; for(int i=0;i<img.get_width();i+=cell_size) { int w = MIN(img.get_width()-i,cell_size); for(int j=0;j<img.get_height();j+=cell_size) { int h = MIN(img.get_height()-j,cell_size); Image piece(w,h,0,img.get_format()); piece.blit_rect(img,Rect2(i,j,w,h),Point2(0,0)); if (!piece.is_invisible()) { pieces[Vector2(i,j)]=piece; //print_line("ADDING PIECE AT "+Vector2(i,j)); } } } Ref<LargeTexture> existing; if (ResourceCache::has(p_path)) { existing = ResourceCache::get(p_path); } if (existing.is_valid()) { existing->clear(); } else { existing = Ref<LargeTexture>(memnew( LargeTexture )); } existing->set_size(Size2(img.get_width(),img.get_height())); pg.step("Inserting",2); for (Map<Vector2,Image>::Element *E=pieces.front();E;E=E->next()) { Ref<ImageTexture> imgtex = Ref<ImageTexture>( memnew( ImageTexture ) ); imgtex->create_from_image(E->get(),tex_flags); _process_texture_data(imgtex,format,quality,flags,p_compr,tex_flags,shrink); existing->add_piece(E->key(),imgtex); } if (!p_external) { from->set_editor(get_name()); existing->set_path(p_path); existing->set_import_metadata(from); } pg.step("Saving",3); err = ResourceSaver::save(p_path,existing); if (err!=OK) { EditorNode::add_io_error("Couldn't save large texture: "+p_path); return err; } return OK; } else if (atlas) { //prepare atlas! Vector< Image > sources; Vector< Image > tsources; bool alpha=false; bool crop = from->get_option("crop"); EditorProgress ep("make_atlas","Build Atlas For: "+p_path.get_file(),from->get_source_count()+3); print_line("sources: "+itos(from->get_source_count())); for(int i=0;i<from->get_source_count();i++) { String path = EditorImportPlugin::expand_source_path(from->get_source_path(i)); String md5 = FileAccess::get_md5(path); from->set_source_md5(i,FileAccess::get_md5(path)); ep.step("Loading Image: "+path,i); print_line("source path: "+path+" md5 "+md5); Image src; Error err = ImageLoader::load_image(path,&src); if (err) { EditorNode::add_io_error("Couldn't load image: "+path); return err; } if (src.detect_alpha()) alpha=true; tsources.push_back(src); } ep.step("Converting Images",sources.size()); int base_index=0; Map<uint64_t,int> source_md5; Map<int,List<int> > source_map; for(int i=0;i<tsources.size();i++) { Image src = tsources[i]; if (alpha) { src.convert(Image::FORMAT_RGBA); } else { src.convert(Image::FORMAT_RGB); } DVector<uint8_t> data = src.get_data(); MD5_CTX md5; DVector<uint8_t>::Read r=data.read(); MD5Init(&md5); int len=data.size(); for(int j=0;j<len;j++) { uint8_t b = r[j]; b>>=2; //to aid in comparing MD5Update(&md5,(unsigned char*)&b,1); } MD5Final(&md5); uint64_t *cmp = (uint64_t*)md5.digest; //less bits, but still useful for this tsources[i]=Image(); //clear if (source_md5.has(*cmp)) { int sidx=source_md5[*cmp]; source_map[sidx].push_back(i); print_line("REUSING "+from->get_source_path(i)); } else { int sidx=sources.size(); source_md5[*cmp]=sidx; sources.push_back(src); List<int> sm; sm.push_back(i); source_map[sidx]=sm; } } //texturepacker is not really good for optimizing, so.. //will at some point likely replace with my own //first, will find the nearest to a square packing int border=1; Vector<Size2i> src_sizes; Vector<Rect2> crops; ep.step("Cropping Images",sources.size()+1); for(int j=0;j<sources.size();j++) { Size2i s; if (crop) { Rect2 crop = sources[j].get_used_rect(); print_line("CROP: "+crop); s=crop.size; crops.push_back(crop); } else { s=Size2i(sources[j].get_width(),sources[j].get_height()); } s+=Size2i(border*2,border*2); src_sizes.push_back(s); //add a line to constraint width } Vector<Point2i> dst_positions; Size2i dst_size; EditorAtlas::fit(src_sizes,dst_positions,dst_size); print_line("size that workeD: "+itos(dst_size.width)+","+itos(dst_size.height)); ep.step("Blitting Images",sources.size()+2); bool blit_to_po2=tex_flags&Texture::FLAG_MIPMAPS; int atlas_w=dst_size.width; int atlas_h=dst_size.height; if (blit_to_po2) { atlas_w=nearest_power_of_2(dst_size.width); atlas_h=nearest_power_of_2(dst_size.height); } Image atlas; atlas.create(atlas_w,atlas_h,0,alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB); atlases.resize(from->get_source_count()); for(int i=0;i<sources.size();i++) { int x=dst_positions[i].x; int y=dst_positions[i].y; Size2 sz = Size2(sources[i].get_width(),sources[i].get_height()); Rect2 region; Rect2 margin; if (crop && sz!=crops[i].size) { Rect2 rect = crops[i]; rect.size=sz-rect.size; region=Rect2(x+border,y+border,crops[i].size.width,crops[i].size.height); margin=rect; atlas.blit_rect(sources[i],crops[i],Point2(x+border,y+border)); } else { region=Rect2(x+border,y+border,sz.x,sz.y); atlas.blit_rect(sources[i],Rect2(0,0,sources[i].get_width(),sources[i].get_height()),Point2(x+border,y+border)); } ERR_CONTINUE( !source_map.has(i) ); for (List<int>::Element *E=source_map[i].front();E;E=E->next()) { String apath = p_path.get_base_dir().plus_file(from->get_source_path(E->get()).get_file().basename()+".atex"); Ref<AtlasTexture> at; if (ResourceCache::has(apath)) { at = Ref<AtlasTexture>( ResourceCache::get(apath)->cast_to<AtlasTexture>() ); } else { at = Ref<AtlasTexture>( memnew( AtlasTexture ) ); } at->set_region(region); at->set_margin(margin); at->set_path(apath); atlases[E->get()]=at; print_line("Atlas Tex: "+apath); } } if (ResourceCache::has(p_path)) { texture = Ref<ImageTexture> ( ResourceCache::get(p_path)->cast_to<ImageTexture>() ); } else { texture = Ref<ImageTexture>( memnew( ImageTexture ) ); } texture->create_from_image(atlas,tex_flags); } else {
Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) { MeshData mesh; #define SUBPLANE_SIZE 1024.0 float subplane_size = 1024.0; // should compute this from the actual plane for (int i = 0; i < p_planes.size(); i++) { Plane p = p_planes[i]; Vector3 ref = Vector3(0.0, 1.0, 0.0); if (ABS(p.normal.dot(ref)) > 0.95) ref = Vector3(0.0, 0.0, 1.0); // change axis Vector3 right = p.normal.cross(ref).normalized(); Vector3 up = p.normal.cross(right).normalized(); Vector<Vector3> vertices; Vector3 center = p.get_any_point(); // make a quad clockwise vertices.push_back(center - up * subplane_size + right * subplane_size); vertices.push_back(center - up * subplane_size - right * subplane_size); vertices.push_back(center + up * subplane_size - right * subplane_size); vertices.push_back(center + up * subplane_size + right * subplane_size); for (int j = 0; j < p_planes.size(); j++) { if (j == i) continue; Vector<Vector3> new_vertices; Plane clip = p_planes[j]; if (clip.normal.dot(p.normal) > 0.95) continue; if (vertices.size() < 3) break; for (int k = 0; k < vertices.size(); k++) { int k_n = (k + 1) % vertices.size(); Vector3 edge0_A = vertices[k]; Vector3 edge1_A = vertices[k_n]; real_t dist0 = clip.distance_to(edge0_A); real_t dist1 = clip.distance_to(edge1_A); if (dist0 <= 0) { // behind plane new_vertices.push_back(vertices[k]); } // check for different sides and non coplanar if ((dist0 * dist1) < 0) { // calculate intersection Vector3 rel = edge1_A - edge0_A; real_t den = clip.normal.dot(rel); if (Math::abs(den) < CMP_EPSILON) continue; // point too short real_t dist = -(clip.normal.dot(edge0_A) - clip.d) / den; Vector3 inters = edge0_A + rel * dist; new_vertices.push_back(inters); } } vertices = new_vertices; } if (vertices.size() < 3) continue; //result is a clockwise face MeshData::Face face; // add face indices for (int j = 0; j < vertices.size(); j++) { int idx = -1; for (int k = 0; k < mesh.vertices.size(); k++) { if (mesh.vertices[k].distance_to(vertices[j]) < 0.001) { idx = k; break; } } if (idx == -1) { idx = mesh.vertices.size(); mesh.vertices.push_back(vertices[j]); } face.indices.push_back(idx); } face.plane = p; mesh.faces.push_back(face); //add edge for (int j = 0; j < face.indices.size(); j++) { int a = face.indices[j]; int b = face.indices[(j + 1) % face.indices.size()]; bool found = false; for (int k = 0; k < mesh.edges.size(); k++) { if (mesh.edges[k].a == a && mesh.edges[k].b == b) { found = true; break; } if (mesh.edges[k].b == a && mesh.edges[k].a == b) { found = true; break; } } if (found) continue; MeshData::Edge edge; edge.a = a; edge.b = b; mesh.edges.push_back(edge); } } return mesh; }
DVector<Face3> Geometry::wrap_geometry(DVector<Face3> p_array, float *p_error) { #define _MIN_SIZE 1.0 #define _MAX_LENGTH 20 int face_count = p_array.size(); DVector<Face3>::Read facesr = p_array.read(); const Face3 *faces = facesr.ptr(); AABB global_aabb; for (int i = 0; i < face_count; i++) { if (i == 0) { global_aabb = faces[i].get_aabb(); } else { global_aabb.merge_with(faces[i].get_aabb()); } } global_aabb.grow_by(0.01); // avoid numerical error // determine amount of cells in grid axis int div_x, div_y, div_z; if (global_aabb.size.x / _MIN_SIZE < _MAX_LENGTH) div_x = (int)(global_aabb.size.x / _MIN_SIZE) + 1; else div_x = _MAX_LENGTH; if (global_aabb.size.y / _MIN_SIZE < _MAX_LENGTH) div_y = (int)(global_aabb.size.y / _MIN_SIZE) + 1; else div_y = _MAX_LENGTH; if (global_aabb.size.z / _MIN_SIZE < _MAX_LENGTH) div_z = (int)(global_aabb.size.z / _MIN_SIZE) + 1; else div_z = _MAX_LENGTH; Vector3 voxelsize = global_aabb.size; voxelsize.x /= div_x; voxelsize.y /= div_y; voxelsize.z /= div_z; // create and initialize cells to zero //print_line("Wrapper: Initializing Cells"); uint8_t ***cell_status = memnew_arr(uint8_t **, div_x); for (int i = 0; i < div_x; i++) { cell_status[i] = memnew_arr(uint8_t *, div_y); for (int j = 0; j < div_y; j++) { cell_status[i][j] = memnew_arr(uint8_t, div_z); for (int k = 0; k < div_z; k++) { cell_status[i][j][k] = 0; } } } // plot faces into cells //print_line("Wrapper (1/6): Plotting Faces"); for (int i = 0; i < face_count; i++) { Face3 f = faces[i]; for (int j = 0; j < 3; j++) { f.vertex[j] -= global_aabb.pos; } _plot_face(cell_status, 0, 0, 0, div_x, div_y, div_z, voxelsize, f); } // determine which cells connect to the outside by traversing the outside and recursively flood-fill marking //print_line("Wrapper (2/6): Flood Filling"); for (int i = 0; i < div_x; i++) { for (int j = 0; j < div_y; j++) { _mark_outside(cell_status, i, j, 0, div_x, div_y, div_z); _mark_outside(cell_status, i, j, div_z - 1, div_x, div_y, div_z); } } for (int i = 0; i < div_z; i++) { for (int j = 0; j < div_y; j++) { _mark_outside(cell_status, 0, j, i, div_x, div_y, div_z); _mark_outside(cell_status, div_x - 1, j, i, div_x, div_y, div_z); } } for (int i = 0; i < div_x; i++) { for (int j = 0; j < div_z; j++) { _mark_outside(cell_status, i, 0, j, div_x, div_y, div_z); _mark_outside(cell_status, i, div_y - 1, j, div_x, div_y, div_z); } } // build faces for the inside-outside cell divisors //print_line("Wrapper (3/6): Building Faces"); DVector<Face3> wrapped_faces; for (int i = 0; i < div_x; i++) { for (int j = 0; j < div_y; j++) { for (int k = 0; k < div_z; k++) { _build_faces(cell_status, i, j, k, div_x, div_y, div_z, wrapped_faces); } } } //print_line("Wrapper (4/6): Transforming Back Vertices"); // transform face vertices to global coords int wrapped_faces_count = wrapped_faces.size(); DVector<Face3>::Write wrapped_facesw = wrapped_faces.write(); Face3 *wrapped_faces_ptr = wrapped_facesw.ptr(); for (int i = 0; i < wrapped_faces_count; i++) { for (int j = 0; j < 3; j++) { Vector3 &v = wrapped_faces_ptr[i].vertex[j]; v = v * voxelsize; v += global_aabb.pos; } } // clean up grid //print_line("Wrapper (5/6): Grid Cleanup"); for (int i = 0; i < div_x; i++) { for (int j = 0; j < div_y; j++) { memdelete_arr(cell_status[i][j]); } memdelete_arr(cell_status[i]); } memdelete_arr(cell_status); if (p_error) *p_error = voxelsize.length(); //print_line("Wrapper (6/6): Finished."); return wrapped_faces; }
jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) { jvalue v; switch(p_type) { case Variant::BOOL: { if (force_jobject) { jclass bclass = env->FindClass("java/lang/Boolean"); jmethodID ctor = env->GetMethodID(bclass, "<init>", "(Z)V"); jvalue val; val.z = (bool)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); v.l = obj; } else { v.z=*p_arg; }; } break; case Variant::INT: { if (force_jobject) { jclass bclass = env->FindClass("java/lang/Integer"); jmethodID ctor = env->GetMethodID(bclass, "<init>", "(I)V"); jvalue val; val.i = (int)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); v.l = obj; } else { v.i=*p_arg; }; } break; case Variant::REAL: { if (force_jobject) { jclass bclass = env->FindClass("java/lang/Double"); jmethodID ctor = env->GetMethodID(bclass, "<init>", "(D)V"); jvalue val; val.d = (double)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); v.l = obj; } else { v.f=*p_arg; }; } break; case Variant::STRING: { String s = *p_arg; jstring jStr = env->NewStringUTF(s.utf8().get_data()); v.l=jStr; } break; case Variant::STRING_ARRAY: { DVector<String> sarray = *p_arg; jobjectArray arr = env->NewObjectArray(sarray.size(),env->FindClass("java/lang/String"),env->NewStringUTF("")); for(int j=0;j<sarray.size();j++) { env->SetObjectArrayElement(arr,j,env->NewStringUTF( sarray[j].utf8().get_data() )); } v.l=arr; } break; case Variant::DICTIONARY: { Dictionary dict = *p_arg; jclass dclass = env->FindClass("com/android/godot/Dictionary"); jmethodID ctor = env->GetMethodID(dclass, "<init>", "()V"); jobject jdict = env->NewObject(dclass, ctor); Array keys = dict.keys(); jobjectArray jkeys = env->NewObjectArray(keys.size(), env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int j=0; j<keys.size(); j++) { env->SetObjectArrayElement(jkeys, j, env->NewStringUTF(String(keys[j]).utf8().get_data())); }; jmethodID set_keys = env->GetMethodID(dclass, "set_keys", "([Ljava/lang/String;)V"); jvalue val; val.l = jkeys; env->CallVoidMethodA(jdict, set_keys, &val); jobjectArray jvalues = env->NewObjectArray(keys.size(), env->FindClass("java/lang/Object"), NULL); for (int j=0; j<keys.size(); j++) { Variant var = dict[keys[j]]; val = _variant_to_jvalue(env, var.get_type(), &var, true); env->SetObjectArrayElement(jvalues, j, val.l); }; jmethodID set_values = env->GetMethodID(dclass, "set_values", "([Ljava/lang/Object;)V"); val.l = jvalues; env->CallVoidMethodA(jdict, set_values, &val); v.l = jdict; } break; case Variant::INT_ARRAY: { DVector<int> array = *p_arg; jintArray arr = env->NewIntArray(array.size()); DVector<int>::Read r = array.read(); env->SetIntArrayRegion(arr,0,array.size(),r.ptr()); v.l=arr; } break; case Variant::RAW_ARRAY: { DVector<uint8_t> array = *p_arg; jbyteArray arr = env->NewByteArray(array.size()); DVector<uint8_t>::Read r = array.read(); env->SetByteArrayRegion(arr,0,array.size(),reinterpret_cast<const signed char*>(r.ptr())); v.l=arr; } break; case Variant::REAL_ARRAY: { DVector<float> array = *p_arg; jfloatArray arr = env->NewFloatArray(array.size()); DVector<float>::Read r = array.read(); env->SetFloatArrayRegion(arr,0,array.size(),r.ptr()); v.l=arr; } break; default: { v.i = 0; } break; } return v; };
void ConcavePolygonShapeSW::_setup(DVector<Vector3> p_faces) { int src_face_count=p_faces.size(); ERR_FAIL_COND(src_face_count%3); src_face_count/=3; DVector<Vector3>::Read r = p_faces.read(); const Vector3 * facesr= r.ptr(); #if 0 Map<Vector3,int> point_map; List<Face> face_list; for(int i=0;i<src_face_count;i++) { Face3 faceaux; for(int j=0;j<3;j++) { faceaux.vertex[j]=facesr[i*3+j].snapped(_POINT_SNAP); //faceaux.vertex[j]=facesr[i*3+j];//facesr[i*3+j].snapped(_POINT_SNAP); } ERR_CONTINUE( faceaux.is_degenerate() ); Face face; for(int j=0;j<3;j++) { Map<Vector3,int>::Element *E=point_map.find(faceaux.vertex[j]); if (E) { face.indices[j]=E->value(); } else { face.indices[j]=point_map.size(); point_map.insert(faceaux.vertex[j],point_map.size()); } } face_list.push_back(face); } vertices.resize( point_map.size() ); DVector<Vector3>::Write vw = vertices.write(); Vector3 *verticesw=vw.ptr(); AABB _aabb; for( Map<Vector3,int>::Element *E=point_map.front();E;E=E->next()) { if (E==point_map.front()) { _aabb.pos=E->key(); } else { _aabb.expand_to(E->key()); } verticesw[E->value()]=E->key(); } point_map.clear(); // not needed anymore faces.resize(face_list.size()); DVector<Face>::Write w = faces.write(); Face *facesw=w.ptr(); int fc=0; for( List<Face>::Element *E=face_list.front();E;E=E->next()) { facesw[fc++]=E->get(); } face_list.clear(); DVector<_VolumeSW_BVH_Element> bvh_array; bvh_array.resize( fc ); DVector<_VolumeSW_BVH_Element>::Write bvhw = bvh_array.write(); _VolumeSW_BVH_Element *bvh_arrayw=bvhw.ptr(); for(int i=0;i<fc;i++) { AABB face_aabb; face_aabb.pos=verticesw[facesw[i].indices[0]]; face_aabb.expand_to( verticesw[facesw[i].indices[1]] ); face_aabb.expand_to( verticesw[facesw[i].indices[2]] ); bvh_arrayw[i].face_index=i; bvh_arrayw[i].aabb=face_aabb; bvh_arrayw[i].center=face_aabb.pos+face_aabb.size*0.5; } w=DVector<Face>::Write(); vw=DVector<Vector3>::Write(); int count=0; _VolumeSW_BVH *bvh_tree=_volume_sw_build_bvh(bvh_arrayw,fc,count); ERR_FAIL_COND(count==0); bvhw=DVector<_VolumeSW_BVH_Element>::Write(); bvh.resize( count+1 ); DVector<BVH>::Write bvhw2 = bvh.write(); BVH*bvh_arrayw2=bvhw2.ptr(); int idx=0; _fill_bvh(bvh_tree,bvh_arrayw2,idx); set_aabb(_aabb); #else DVector<_VolumeSW_BVH_Element> bvh_array; bvh_array.resize( src_face_count ); DVector<_VolumeSW_BVH_Element>::Write bvhw = bvh_array.write(); _VolumeSW_BVH_Element *bvh_arrayw=bvhw.ptr(); faces.resize(src_face_count); DVector<Face>::Write w = faces.write(); Face *facesw=w.ptr(); vertices.resize( src_face_count*3 ); DVector<Vector3>::Write vw = vertices.write(); Vector3 *verticesw=vw.ptr(); AABB _aabb; for(int i=0;i<src_face_count;i++) { Face3 face( facesr[i*3+0], facesr[i*3+1], facesr[i*3+2] ); bvh_arrayw[i].aabb=face.get_aabb(); bvh_arrayw[i].center = bvh_arrayw[i].aabb.pos + bvh_arrayw[i].aabb.size * 0.5; bvh_arrayw[i].face_index=i; facesw[i].indices[0]=i*3+0; facesw[i].indices[1]=i*3+1; facesw[i].indices[2]=i*3+2; facesw[i].normal=face.get_plane().normal; verticesw[i*3+0]=face.vertex[0]; verticesw[i*3+1]=face.vertex[1]; verticesw[i*3+2]=face.vertex[2]; if (i==0) _aabb=bvh_arrayw[i].aabb; else _aabb.merge_with(bvh_arrayw[i].aabb); } w=DVector<Face>::Write(); vw=DVector<Vector3>::Write(); int count=0; _VolumeSW_BVH *bvh_tree=_volume_sw_build_bvh(bvh_arrayw,src_face_count,count); bvh.resize( count+1 ); DVector<BVH>::Write bvhw2 = bvh.write(); BVH*bvh_arrayw2=bvhw2.ptr(); int idx=0; _fill_bvh(bvh_tree,bvh_arrayw2,idx); configure(_aabb); // this type of shape has no margin #endif }
DVector(const DVector& other) : Base(other.size()) { elements_ = other.elements_; }
bool D_bjmak::sendBuffer(QVector<FileID>& ids, qint64 bufferSize){ //QString idsBuffer; //QString hashBuffer; //QString dataBuffer; std::cout << "sending buffer of " << ids.size() << std::endl; server->connectionPtr->sendMsg("NEXT"); const int hashBufferSize = bufferSize / bsize_; DVector hashBuffer; hashBuffer.reserve(hashBufferSize); DVector dataBuffer; hashBuffer.reserve(bufferSize); DVector idsBuffer; hashBuffer.reserve(3000000); int blockCount; int fd; bool isCleared = true; for(int i = 0; i < ids.size(); ++i){ if (!ids[i].isREG()){ idsBuffer.push_back(ids[i].toString()); //cout << "added not reg " << ids[i].getFullPath().toStdString() << endl; continue; } DVector tmpHashBuffer; DVector tmpDataBuffer; if ( (dataBuffer.size()+ids[i].getSize()) > bufferSize ){ blockCount = (bufferSize-dataBuffer.size()) / bsize_; isCleared = false; } else{ blockCount = ids[i].getSize() / bsize_; if ( (ids[i].getSize() % bsize_) != 0 ) ++blockCount; } fd = open(ids[i].getFullPath().toStdString().c_str(), O_RDONLY); if (fd == -1){ cout << "error " << strerror(errno) << endl; writeLog.warning() << "Error open file <" << ids[i].getFullPath() << "> " << strerror(errno) << DebusLogger::endl; continue; } if (!getHashesAndData(fd, tmpDataBuffer, tmpHashBuffer, blockCount)){ cout << "error " << strerror(errno) << endl; writeLog.warning() << "Error read file <" << ids[i].getFullPath() << "> " << strerror(errno) << DebusLogger::endl; continue; } idsBuffer.push_back(ids[i].toString()); //cout << "added reg " << ids[i].getFullPath().toStdString() << endl; //idsBuffer.push_back(ids[i].toQString()); hashBuffer.push_back(tmpHashBuffer); dataBuffer.push_back(tmpDataBuffer); if (isCleared) close(fd); } cout << "Sending idsbuffer " << idsBuffer.size() << endl; server->connectionPtr->sendMsg(idsBuffer.data(), idsBuffer.size()); cout << "Sending hashBuffer " << hashBuffer.size() << endl; server->connectionPtr->sendMsg(hashBuffer.data(), hashBuffer.size()); server->connectionPtr->recvMsg(); DVector reply; reply.push_back(server->connectionPtr->dataToVector()); cout << "Received reply size " << reply.size() << endl; DVector newDataBuffer; newDataBuffer = this->getDataBufferFromReply(reply, hashBuffer, dataBuffer); cout << "sending data size " << newDataBuffer.size() << endl; server->connectionPtr->sendMsg(newDataBuffer.data(), newDataBuffer.size()); if (!isCleared){ int clearedBlockCount = blockCount; blockCount = ids.last().getSize() / bsize_; if ( (ids.last().getSize() % bsize_) != 0 ) ++blockCount; blockCount -= clearedBlockCount; while(blockCount){ int i; if (blockCount*bsize_ > bufferSize) i = bufferSize/bsize_; else i = blockCount; cout << "bufferSize " << bufferSize << " " << " i " << i << endl; dataBuffer.clear(); hashBuffer.clear(); getHashesAndData(fd, dataBuffer, hashBuffer, i); cout << "dataBuffer" << dataBuffer.size() << " " << "hashBuffer" << hashBuffer.size() << endl; server->connectionPtr->sendMsg(hashBuffer.data(), hashBuffer.size()); cout << "clearedBlockCount" << clearedBlockCount << " " << "blockCount" << blockCount << endl; server->connectionPtr->recvMsg(); cout << "clearedBlockCount" << clearedBlockCount << " " << "blockCount" << blockCount << endl; DVector reply; reply.push_back(server->connectionPtr->dataToString()); DVector newDataBuffer; newDataBuffer = this->getDataBufferFromReply(reply, hashBuffer, dataBuffer); server->connectionPtr->sendMsg(newDataBuffer.data(), newDataBuffer.size()); blockCount -= i; } close(fd); } cout << "sended block" << endl; return true; }
void Polygon2DEditor::_uv_draw() { Ref<Texture> base_tex = node->get_texture(); if (base_tex.is_null()) return; Matrix32 mtx; mtx.elements[2]=-uv_draw_ofs; mtx.scale_basis(Vector2(uv_draw_zoom,uv_draw_zoom)); VS::get_singleton()->canvas_item_set_clip(uv_edit_draw->get_canvas_item(),true); VS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(),mtx); uv_edit_draw->draw_texture(base_tex,Point2()); VS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(),Matrix32()); if (snap_show_grid) { Size2 s = uv_edit_draw->get_size(); int last_cell; if (snap_step.x!=0) { for(int i=0;i<s.width;i++) { int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(i,0)).x-snap_offset.x)/snap_step.x)); if (i==0) last_cell=cell; if (last_cell!=cell) uv_edit_draw->draw_line(Point2(i,0),Point2(i,s.height),Color(0.3,0.7,1,0.3)); last_cell=cell; } } if (snap_step.y!=0) { for(int i=0;i<s.height;i++) { int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(0,i)).y-snap_offset.y)/snap_step.y)); if (i==0) last_cell=cell; if (last_cell!=cell) uv_edit_draw->draw_line(Point2(0,i),Point2(s.width,i),Color(0.3,0.7,1,0.3)); last_cell=cell; } } } DVector<Vector2> uvs = node->get_uv(); Ref<Texture> handle = get_icon("EditorHandle","EditorIcons"); Rect2 rect(Point2(),mtx.basis_xform(base_tex->get_size())); rect.expand_to(mtx.basis_xform(uv_edit_draw->get_size())); for(int i=0;i<uvs.size();i++) { int next = (i+1)%uvs.size(); uv_edit_draw->draw_line(mtx.xform(uvs[i]),mtx.xform(uvs[next]),Color(0.9,0.5,0.5),2); uv_edit_draw->draw_texture(handle,mtx.xform(uvs[i])-handle->get_size()*0.5); rect.expand_to(mtx.basis_xform(uvs[i])); } rect=rect.grow(200); updating_uv_scroll=true; uv_hscroll->set_min(rect.pos.x); uv_hscroll->set_max(rect.pos.x+rect.size.x); uv_hscroll->set_page(uv_edit_draw->get_size().x); uv_hscroll->set_val(uv_draw_ofs.x); uv_hscroll->set_step(0.001); uv_vscroll->set_min(rect.pos.y); uv_vscroll->set_max(rect.pos.y+rect.size.y); uv_vscroll->set_page(uv_edit_draw->get_size().y); uv_vscroll->set_val(uv_draw_ofs.y); uv_vscroll->set_step(0.001); updating_uv_scroll=false; }
void SceneState::set_bundled_scene(const Dictionary& d) { ERR_FAIL_COND( !d.has("names")); ERR_FAIL_COND( !d.has("variants")); ERR_FAIL_COND( !d.has("node_count")); ERR_FAIL_COND( !d.has("nodes")); ERR_FAIL_COND( !d.has("conn_count")); ERR_FAIL_COND( !d.has("conns")); // ERR_FAIL_COND( !d.has("path")); int version=1; if (d.has("version")) version=d["version"]; if (version>PACK_VERSION) { ERR_EXPLAIN("Save format version too new!"); ERR_FAIL(); } DVector<String> snames = d["names"]; if (snames.size()) { int namecount = snames.size(); names.resize(namecount); DVector<String>::Read r =snames.read(); for(int i=0;i<names.size();i++) names[i]=r[i]; } Array svariants = d["variants"]; if (svariants.size()) { int varcount=svariants.size(); variants.resize(varcount); for(int i=0;i<varcount;i++) { variants[i]=svariants[i]; } } else { variants.clear(); } nodes.resize(d["node_count"]); int nc=nodes.size(); if (nc) { DVector<int> snodes = d["nodes"]; DVector<int>::Read r = snodes.read(); int idx=0; for(int i=0;i<nc;i++) { NodeData &nd = nodes[i]; nd.parent=r[idx++]; nd.owner=r[idx++]; nd.type=r[idx++]; nd.name=r[idx++]; nd.instance=r[idx++]; nd.properties.resize(r[idx++]); for(int j=0;j<nd.properties.size();j++) { nd.properties[j].name=r[idx++]; nd.properties[j].value=r[idx++]; } nd.groups.resize(r[idx++]); for(int j=0;j<nd.groups.size();j++) { nd.groups[j]=r[idx++]; } } } connections.resize(d["conn_count"]); int cc=connections.size(); if (cc) { DVector<int> sconns = d["conns"]; DVector<int>::Read r = sconns.read(); int idx=0; for(int i=0;i<cc;i++) { ConnectionData &cd = connections[i]; cd.from=r[idx++]; cd.to=r[idx++]; cd.signal=r[idx++]; cd.method=r[idx++]; cd.flags=r[idx++]; cd.binds.resize(r[idx++]); for(int j=0;j<cd.binds.size();j++) { cd.binds[j]=r[idx++]; } } } Array np; if (d.has("node_paths")) { np=d["node_paths"]; } node_paths.resize(np.size()); for(int i=0;i<np.size();i++) { node_paths[i]=np[i]; } Array ei; if (d.has("editable_instances")) { ei=d["editable_instances"]; } if (d.has("base_scene")) { base_scene_idx=d["base_scene"]; } editable_instances.resize(ei.size()); for(int i=0;i<editable_instances.size();i++) { editable_instances[i]=ei[i]; } // path=d["path"]; }
static String _encode_variant(const Variant& p_variant) { switch(p_variant.get_type()) { case Variant::BOOL: { bool val = p_variant; return (val?"true":"false"); } break; case Variant::INT: { int val = p_variant; return itos(val); } break; case Variant::REAL: { float val = p_variant; return rtos(val)+(val==int(val)?".0":""); } break; case Variant::STRING: { String val = p_variant; return "\""+val.xml_escape()+"\""; } break; case Variant::COLOR: { Color val = p_variant; return "#"+val.to_html(); } break; case Variant::STRING_ARRAY: case Variant::INT_ARRAY: case Variant::REAL_ARRAY: case Variant::ARRAY: { Array arr = p_variant; String str="["; for(int i=0;i<arr.size();i++) { if (i>0) str+=", "; str+=_encode_variant(arr[i]); } str+="]"; return str; } break; case Variant::DICTIONARY: { Dictionary d = p_variant; String str="{"; List<Variant> keys; d.get_key_list(&keys); for(List<Variant>::Element *E=keys.front();E;E=E->next()) { if (E!=keys.front()) str+=", "; str+=_encode_variant(E->get()); str+=":"; str+=_encode_variant(d[E->get()]); } str+="}"; return str; } break; case Variant::IMAGE: { String str="img("; Image img=p_variant; if (!img.empty()) { String format; switch(img.get_format()) { case Image::FORMAT_GRAYSCALE: format="grayscale"; break; case Image::FORMAT_INTENSITY: format="intensity"; break; case Image::FORMAT_GRAYSCALE_ALPHA: format="grayscale_alpha"; break; case Image::FORMAT_RGB: format="rgb"; break; case Image::FORMAT_RGBA: format="rgba"; break; case Image::FORMAT_INDEXED : format="indexed"; break; case Image::FORMAT_INDEXED_ALPHA: format="indexed_alpha"; break; case Image::FORMAT_BC1: format="bc1"; break; case Image::FORMAT_BC2: format="bc2"; break; case Image::FORMAT_BC3: format="bc3"; break; case Image::FORMAT_BC4: format="bc4"; break; case Image::FORMAT_BC5: format="bc5"; break; case Image::FORMAT_CUSTOM: format="custom custom_size="+itos(img.get_data().size())+""; break; default: {} } str+=format+", "; str+=itos(img.get_mipmaps())+", "; str+=itos(img.get_width())+", "; str+=itos(img.get_height())+", "; DVector<uint8_t> data = img.get_data(); int ds=data.size(); DVector<uint8_t>::Read r = data.read(); for(int i=0;i<ds;i++) { uint8_t byte = r[i]; const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char bstr[3]={ hex[byte>>4], hex[byte&0xF], 0}; str+=bstr; } } str+=")"; return str; } break; case Variant::INPUT_EVENT: { InputEvent ev = p_variant; switch(ev.type) { case InputEvent::KEY: { String mods; if (ev.key.mod.control) mods+="C"; if (ev.key.mod.shift) mods+="S"; if (ev.key.mod.alt) mods+="A"; if (ev.key.mod.meta) mods+="M"; if (mods!="") mods=", "+mods; return "key("+keycode_get_string(ev.key.scancode)+mods+")"; } break; case InputEvent::MOUSE_BUTTON: { return "mbutton("+itos(ev.device)+", "+itos(ev.mouse_button.button_index)+")"; } break; case InputEvent::JOYSTICK_BUTTON: { return "jbutton("+itos(ev.device)+", "+itos(ev.joy_button.button_index)+")"; } break; case InputEvent::JOYSTICK_MOTION: { return "jaxis("+itos(ev.device)+", "+itos(ev.joy_motion.axis)+")"; } break; default: { return "nil"; } break; } } break; default: {} }
Error MeshDataTool::commit_to_surface(const Ref<Mesh>& p_mesh) { ERR_FAIL_COND_V(p_mesh.is_null(),ERR_INVALID_PARAMETER); Array arr; arr.resize(Mesh::ARRAY_MAX); int vcount=vertices.size(); DVector<Vector3> v; DVector<Vector3> n; DVector<real_t> t; DVector<Vector2> u; DVector<Vector2> u2; DVector<Color> c; DVector<real_t> b; DVector<real_t> w; DVector<int> in; { v.resize(vcount); DVector<Vector3>::Write vr=v.write(); DVector<Vector3>::Write nr; if (format&Mesh::ARRAY_FORMAT_NORMAL) { n.resize(vcount); nr = n.write(); } DVector<real_t>::Write ta; if (format&Mesh::ARRAY_FORMAT_TANGENT) { t.resize(vcount*4); ta = t.write(); } DVector<Vector2>::Write uv; if (format&Mesh::ARRAY_FORMAT_TEX_UV) { u.resize(vcount); uv = u.write(); } DVector<Vector2>::Write uv2; if (format&Mesh::ARRAY_FORMAT_TEX_UV2) { u2.resize(vcount); uv2 = u2.write(); } DVector<Color>::Write col; if (format&Mesh::ARRAY_FORMAT_COLOR) { c.resize(vcount); col = c.write(); } DVector<real_t>::Write bo; if (format&Mesh::ARRAY_FORMAT_BONES) { b.resize(vcount*4); bo = b.write(); } DVector<real_t>::Write we; if (format&Mesh::ARRAY_FORMAT_WEIGHTS) { w.resize(vcount*4); we = w.write(); } for(int i=0;i<vcount;i++) { Vertex &vtx=vertices[i]; vr[i]=vtx.vertex; if (nr.ptr()) nr[i]=vtx.normal; if (ta.ptr()) { ta[i*4+0]=vtx.tangent.normal.x; ta[i*4+1]=vtx.tangent.normal.y; ta[i*4+2]=vtx.tangent.normal.z; ta[i*4+3]=vtx.tangent.d; } if (uv.ptr()) uv[i]=vtx.uv; if (uv2.ptr()) uv2[i]=vtx.uv2; if (col.ptr()) col[i]=vtx.color; if (we.ptr()) { we[i*4+0]=vtx.weights[0]; we[i*4+1]=vtx.weights[1]; we[i*4+2]=vtx.weights[2]; we[i*4+3]=vtx.weights[3]; } if (bo.ptr()) { bo[i*4+0]=vtx.bones[0]; bo[i*4+1]=vtx.bones[1]; bo[i*4+2]=vtx.bones[2]; bo[i*4+3]=vtx.bones[3]; } } int fc = faces.size(); in.resize(fc*3); DVector<int>::Write iw=in.write(); for(int i=0;i<fc;i++) { iw[i*3+0]=faces[i].v[0]; iw[i*3+1]=faces[i].v[1]; iw[i*3+2]=faces[i].v[2]; } } arr[Mesh::ARRAY_VERTEX]=v; arr[Mesh::ARRAY_INDEX]=in; if (n.size()) arr[Mesh::ARRAY_NORMAL]=n; if (c.size()) arr[Mesh::ARRAY_COLOR]=c; if (u.size()) arr[Mesh::ARRAY_TEX_UV]=u; if (u2.size()) arr[Mesh::ARRAY_TEX_UV2]=u2; if (t.size()) arr[Mesh::ARRAY_TANGENT]=t; if (b.size()) arr[Mesh::ARRAY_BONES]=b; if (w.size()) arr[Mesh::ARRAY_WEIGHTS]=w; Ref<Mesh> ncmesh=p_mesh; int sc = ncmesh->get_surface_count(); ncmesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,arr); ncmesh->surface_set_material(sc,material); return OK; }
static void _decompress_etc(Image *p_img) { ERR_FAIL_COND(p_img->get_format()!=Image::FORMAT_ETC); int imgw = p_img->get_width(); int imgh = p_img->get_height(); DVector<uint8_t> src=p_img->get_data(); DVector<uint8_t> dst; DVector<uint8_t>::Read r = src.read(); int mmc=p_img->get_mipmap_count(); for(int i=0;i<=mmc;i++) { dst.resize(dst.size()+imgw*imgh*3); const uint8_t *srcbr=&r[p_img->get_mipmap_offset(i)]; DVector<uint8_t>::Write w = dst.write(); uint8_t *wptr = &w[dst.size()-imgw*imgh*3]; int bw=MAX(imgw/4,1); int bh=MAX(imgh/4,1); for(int y=0;y<bh;y++) { for(int x=0;x<bw;x++) { uint8_t block[4*4*4]; rg_etc1::unpack_etc1_block(srcbr,(unsigned int*)block); srcbr+=8; int maxx=MIN(imgw,4); int maxy=MIN(imgh,4); for(int yy=0;yy<maxy;yy++) { for(int xx=0;xx<maxx;xx++) { uint32_t src_ofs = (yy*4+xx)*4; uint32_t dst_ofs = ((y*4+yy)*imgw+x*4+xx)*3; wptr[dst_ofs+0]=block[src_ofs+0]; wptr[dst_ofs+1]=block[src_ofs+1]; wptr[dst_ofs+2]=block[src_ofs+2]; } } } } imgw=MAX(1,imgw/2); imgh=MAX(1,imgh/2); } r=DVector<uint8_t>::Read(); //print_line("Re Creating ETC into regular image: w "+itos(p_img->get_width())+" h "+itos(p_img->get_height())+" mm "+itos(p_img->get_mipmaps())); *p_img=Image(p_img->get_width(),p_img->get_height(),p_img->has_mipmaps(),Image::FORMAT_RGB8,dst); if (p_img->has_mipmaps()) p_img->generate_mipmaps(true); }
Error MeshDataTool::create_from_surface(const Ref<Mesh>& p_mesh,int p_surface) { ERR_FAIL_COND_V(p_mesh.is_null(),ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_mesh.is_null(),ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_mesh->surface_get_primitive_type(p_surface)!=Mesh::PRIMITIVE_TRIANGLES,ERR_INVALID_PARAMETER); Array arrays = p_mesh->surface_get_arrays(p_surface); ERR_FAIL_COND_V( arrays.empty(), ERR_INVALID_PARAMETER ); DVector<Vector3> varray = arrays[Mesh::ARRAY_VERTEX]; int vcount = varray.size(); ERR_FAIL_COND_V( vcount == 0, ERR_INVALID_PARAMETER); clear(); format = p_mesh->surface_get_format(p_surface); material=p_mesh->surface_get_material(p_surface); DVector<Vector3>::Read vr = varray.read(); DVector<Vector3>::Read nr; if (arrays[Mesh::ARRAY_NORMAL].get_type()!=Variant::NIL) nr = arrays[Mesh::ARRAY_NORMAL].operator DVector<Vector3>().read(); DVector<real_t>::Read ta; if (arrays[Mesh::ARRAY_TANGENT].get_type()!=Variant::NIL) ta = arrays[Mesh::ARRAY_TANGENT].operator DVector<real_t>().read(); DVector<Vector2>::Read uv; if (arrays[Mesh::ARRAY_TEX_UV].get_type()!=Variant::NIL) uv = arrays[Mesh::ARRAY_TEX_UV].operator DVector<Vector2>().read(); DVector<Vector2>::Read uv2; if (arrays[Mesh::ARRAY_TEX_UV2].get_type()!=Variant::NIL) uv2 = arrays[Mesh::ARRAY_TEX_UV2].operator DVector<Vector2>().read(); DVector<Color>::Read col; if (arrays[Mesh::ARRAY_COLOR].get_type()!=Variant::NIL) col = arrays[Mesh::ARRAY_COLOR].operator DVector<Color>().read(); DVector<real_t>::Read bo; if (arrays[Mesh::ARRAY_BONES].get_type()!=Variant::NIL) bo = arrays[Mesh::ARRAY_BONES].operator DVector<real_t>().read(); DVector<real_t>::Read we; if (arrays[Mesh::ARRAY_WEIGHTS].get_type()!=Variant::NIL) we = arrays[Mesh::ARRAY_WEIGHTS].operator DVector<real_t>().read(); vertices.resize(vcount); for(int i=0;i<vcount;i++) { Vertex v; v.vertex=vr[i]; if (nr.ptr()) v.normal=nr[i]; if (ta.ptr()) v.tangent=Plane(ta[i*4+0],ta[i*4+1],ta[i*4+2],ta[i*4+3]); if (uv.ptr()) v.uv=uv[i]; if (uv2.ptr()) v.uv2=uv2[i]; if (col.ptr()) v.color=col[i]; if (we.ptr()) { v.weights.push_back(we[i*4+0]); v.weights.push_back(we[i*4+1]); v.weights.push_back(we[i*4+2]); v.weights.push_back(we[i*4+3]); } if (bo.ptr()) { v.bones.push_back(bo[i*4+0]); v.bones.push_back(bo[i*4+1]); v.bones.push_back(bo[i*4+2]); v.bones.push_back(bo[i*4+3]); } vertices[i]=v; } DVector<int> indices; if (arrays[Mesh::ARRAY_INDEX].get_type()!=Variant::NIL) { indices = arrays[Mesh::ARRAY_INDEX]; } else { //make code simpler indices.resize(vcount); DVector<int>::Write iw=indices.write(); for(int i=0;i<vcount;i++) iw[i]=i; } int icount=indices.size(); DVector<int>::Read r = indices.read(); Map<Point2i,int> edge_indices; for(int i=0;i<icount;i+=3) { Vertex*v[3]={ &vertices[r[i+0]], &vertices[r[i+1]], &vertices[r[i+2]] }; int fidx=faces.size(); Face face; for(int j=0;j<3;j++) { face.v[j]=r[i+j]; Point2i edge(r[i+j],r[i+(j+1)%3]); if (edge.x > edge.y) { SWAP(edge.x,edge.y); } if (edge_indices.has(edge)) { face.edges[j]=edge_indices[edge]; } else { face.edges[j]=edge_indices.size(); edge_indices[edge]=face.edges[j]; Edge e; e.vertex[0]=edge.x; e.vertex[1]=edge.y; edges.push_back(e); } edges[face.edges[j]].faces.push_back(fidx); v[j]->faces.push_back(fidx); v[j]->edges.push_back(face.edges[j]); } faces.push_back(face); } return OK; }
Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,int &line,String &r_err_str,ResourceParser *p_res_parser) { /* { Error err = get_token(p_stream,token,line,r_err_str); if (err) return err; }*/ if (token.type==TK_CURLY_BRACKET_OPEN) { Dictionary d; Error err = _parse_dictionary(d,p_stream,line,r_err_str,p_res_parser); if (err) return err; value=d; return OK; } else if (token.type==TK_BRACKET_OPEN) { Array a; Error err = _parse_array(a,p_stream,line,r_err_str,p_res_parser); if (err) return err; value=a; return OK; } else if (token.type==TK_IDENTIFIER) { /* VECTOR2, // 5 RECT2, VECTOR3, MATRIX32, PLANE, QUAT, // 10 _AABB, //sorry naming convention fail :( not like it's used often MATRIX3, TRANSFORM, // misc types COLOR, IMAGE, // 15 NODE_PATH, _RID, OBJECT, INPUT_EVENT, DICTIONARY, // 20 ARRAY, // arrays RAW_ARRAY, INT_ARRAY, REAL_ARRAY, STRING_ARRAY, // 25 VECTOR2_ARRAY, VECTOR3_ARRAY, COLOR_ARRAY, VARIANT_MAX */ String id = token.value; if (id=="true") value=true; else if (id=="false") value=false; else if (id=="null" || id=="nil") value=Variant(); else if (id=="Vector2"){ Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=2) { r_err_str="Expected 2 arguments for constructor"; } value=Vector2(args[0],args[1]); return OK; } else if (id=="Rect2"){ Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=4) { r_err_str="Expected 4 arguments for constructor"; } value=Rect2(args[0],args[1],args[2],args[3]); return OK; } else if (id=="Vector3"){ Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=3) { r_err_str="Expected 3 arguments for constructor"; } value=Vector3(args[0],args[1],args[2]); return OK; } else if (id=="Matrix32"){ Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=6) { r_err_str="Expected 6 arguments for constructor"; } Matrix32 m; m[0]=Vector2(args[0],args[1]); m[1]=Vector2(args[2],args[3]); m[2]=Vector2(args[4],args[5]); value=m; return OK; } else if (id=="Plane") { Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=4) { r_err_str="Expected 4 arguments for constructor"; } value=Plane(args[0],args[1],args[2],args[3]); return OK; } else if (id=="Quat") { Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=4) { r_err_str="Expected 4 arguments for constructor"; } value=Quat(args[0],args[1],args[2],args[3]); return OK; } else if (id=="AABB"){ Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=6) { r_err_str="Expected 6 arguments for constructor"; } value=AABB(Vector3(args[0],args[1],args[2]),Vector3(args[3],args[4],args[5])); return OK; } else if (id=="Matrix3"){ Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=9) { r_err_str="Expected 9 arguments for constructor"; } value=Matrix3(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]); return OK; } else if (id=="Transform"){ Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=12) { r_err_str="Expected 12 arguments for constructor"; } value=Transform(Matrix3(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]),Vector3(args[9],args[10],args[11])); return OK; } else if (id=="Color") { Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; if (args.size()!=4) { r_err_str="Expected 4 arguments for constructor"; } value=Color(args[0],args[1],args[2],args[3]); return OK; } else if (id=="Image") { //:| get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_OPEN) { r_err_str="Expected '('"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type==TK_PARENTHESIS_CLOSE) { value=Image(); // just an Image() return OK; } else if (token.type!=TK_NUMBER) { r_err_str="Expected number (width)"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); int width=token.value; if (token.type!=TK_COMMA) { r_err_str="Expected ','"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_NUMBER) { r_err_str="Expected number (height)"; return ERR_PARSE_ERROR; } int height=token.value; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_COMMA) { r_err_str="Expected ','"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_NUMBER) { r_err_str="Expected number (mipmaps)"; return ERR_PARSE_ERROR; } int mipmaps=token.value; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_COMMA) { r_err_str="Expected ','"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_IDENTIFIER) { r_err_str="Expected identifier (format)"; return ERR_PARSE_ERROR; } String sformat=token.value; Image::Format format; if (sformat=="GRAYSCALE") format=Image::FORMAT_GRAYSCALE; else if (sformat=="INTENSITY") format=Image::FORMAT_INTENSITY; else if (sformat=="GRAYSCALE_ALPHA") format=Image::FORMAT_GRAYSCALE_ALPHA; else if (sformat=="RGB") format=Image::FORMAT_RGB; else if (sformat=="RGBA") format=Image::FORMAT_RGBA; else if (sformat=="INDEXED") format=Image::FORMAT_INDEXED; else if (sformat=="INDEXED_ALPHA") format=Image::FORMAT_INDEXED_ALPHA; else if (sformat=="BC1") format=Image::FORMAT_BC1; else if (sformat=="BC2") format=Image::FORMAT_BC2; else if (sformat=="BC3") format=Image::FORMAT_BC3; else if (sformat=="BC4") format=Image::FORMAT_BC4; else if (sformat=="BC5") format=Image::FORMAT_BC5; else if (sformat=="PVRTC2") format=Image::FORMAT_PVRTC2; else if (sformat=="PVRTC2_ALPHA") format=Image::FORMAT_PVRTC2_ALPHA; else if (sformat=="PVRTC4") format=Image::FORMAT_PVRTC4; else if (sformat=="PVRTC4_ALPHA") format=Image::FORMAT_PVRTC4_ALPHA; else if (sformat=="ATC") format=Image::FORMAT_ATC; else if (sformat=="ATC_ALPHA_EXPLICIT") format=Image::FORMAT_ATC_ALPHA_EXPLICIT; else if (sformat=="ATC_ALPHA_INTERPOLATED") format=Image::FORMAT_ATC_ALPHA_INTERPOLATED; else if (sformat=="CUSTOM") format=Image::FORMAT_CUSTOM; else { r_err_str="Invalid image format: '"+sformat+"'"; return ERR_PARSE_ERROR; }; int len = Image::get_image_data_size(width,height,format,mipmaps); DVector<uint8_t> buffer; buffer.resize(len); if (buffer.size()!=len) { r_err_str="Couldn't allocate image buffer of size: "+itos(len); } { DVector<uint8_t>::Write w=buffer.write(); for(int i=0;i<len;i++) { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_COMMA) { r_err_str="Expected ','"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_NUMBER) { r_err_str="Expected number"; return ERR_PARSE_ERROR; } w[i]=int(token.value); } } Image img(width,height,mipmaps,format,buffer); value=img; return OK; } else if (id=="NodePath") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_OPEN) { r_err_str="Expected '('"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_STRING) { r_err_str="Expected string as argument for NodePath()"; return ERR_PARSE_ERROR; } value=NodePath(String(token.value)); get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_CLOSE) { r_err_str="Expected ')'"; return ERR_PARSE_ERROR; } } else if (id=="RID") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_OPEN) { r_err_str="Expected '('"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_NUMBER) { r_err_str="Expected number as argument"; return ERR_PARSE_ERROR; } value=token.value; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_CLOSE) { r_err_str="Expected ')'"; return ERR_PARSE_ERROR; } return OK; } else if (id=="Resource" || id=="SubResource" || id=="ExtResource") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_OPEN) { r_err_str="Expected '('"; return ERR_PARSE_ERROR; } if (p_res_parser && id=="Resource" && p_res_parser->func){ RES res; Error err = p_res_parser->func(p_res_parser->userdata,p_stream,res,line,r_err_str); if (err) return err; value=res; return OK; } else if (p_res_parser && id=="ExtResource" && p_res_parser->ext_func){ RES res; Error err = p_res_parser->ext_func(p_res_parser->userdata,p_stream,res,line,r_err_str); if (err) return err; value=res; return OK; } else if (p_res_parser && id=="SubResource" && p_res_parser->sub_func){ RES res; Error err = p_res_parser->sub_func(p_res_parser->userdata,p_stream,res,line,r_err_str); if (err) return err; value=res; return OK; } else { get_token(p_stream,token,line,r_err_str); if (token.type==TK_STRING) { String path=token.value; RES res = ResourceLoader::load(path); if (res.is_null()) { r_err_str="Can't load resource at path: '"+path+"'."; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_CLOSE) { r_err_str="Expected ')'"; return ERR_PARSE_ERROR; } value=res; return OK; } else { r_err_str="Expected string as argument for Resource()."; return ERR_PARSE_ERROR; } } return OK; } else if (id=="InputEvent") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_OPEN) { r_err_str="Expected '('"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_IDENTIFIER) { r_err_str="Expected identifier"; return ERR_PARSE_ERROR; } String id = token.value; InputEvent ie; if (id=="KEY") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_COMMA) { r_err_str="Expected ','"; return ERR_PARSE_ERROR; } ie.type=InputEvent::KEY; get_token(p_stream,token,line,r_err_str); if (token.type==TK_IDENTIFIER) { String name=token.value; ie.key.scancode=find_keycode(name); } else if (token.type==TK_NUMBER) { ie.key.scancode=token.value; } else { r_err_str="Expected string or integer for keycode"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type==TK_COMMA) { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_IDENTIFIER) { r_err_str="Expected identifier with modifier flas"; return ERR_PARSE_ERROR; } String mods=token.value; if (mods.findn("C")!=-1) ie.key.mod.control=true; if (mods.findn("A")!=-1) ie.key.mod.alt=true; if (mods.findn("S")!=-1) ie.key.mod.shift=true; if (mods.findn("M")!=-1) ie.key.mod.meta=true; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_CLOSE) { r_err_str="Expected ')'"; return ERR_PARSE_ERROR; } } else if (token.type!=TK_PARENTHESIS_CLOSE) { r_err_str="Expected ')' or modifier flags."; return ERR_PARSE_ERROR; } } else if (id=="MBUTTON") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_COMMA) { r_err_str="Expected ','"; return ERR_PARSE_ERROR; } ie.type=InputEvent::MOUSE_BUTTON; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_NUMBER) { r_err_str="Expected button index"; return ERR_PARSE_ERROR; } ie.mouse_button.button_index = token.value; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_CLOSE) { r_err_str="Expected ')'"; return ERR_PARSE_ERROR; } } else if (id=="JBUTTON") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_COMMA) { r_err_str="Expected ','"; return ERR_PARSE_ERROR; } ie.type=InputEvent::JOYSTICK_BUTTON; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_NUMBER) { r_err_str="Expected button index"; return ERR_PARSE_ERROR; } ie.joy_button.button_index = token.value; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_CLOSE) { r_err_str="Expected ')'"; return ERR_PARSE_ERROR; } } else if (id=="JAXIS") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_COMMA) { r_err_str="Expected ','"; return ERR_PARSE_ERROR; } ie.type=InputEvent::JOYSTICK_MOTION; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_NUMBER) { r_err_str="Expected axis index"; return ERR_PARSE_ERROR; } ie.joy_motion.axis = token.value; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_COMMA) { r_err_str="Expected ',' after axis index"; return ERR_PARSE_ERROR; } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_NUMBER) { r_err_str="Expected axis sign"; return ERR_PARSE_ERROR; } ie.joy_motion.axis_value = token.value; get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_CLOSE) { r_err_str="Expected ')' for jaxis"; return ERR_PARSE_ERROR; } } else { r_err_str="Invalid input event type."; return ERR_PARSE_ERROR; } value=ie; return OK; } else if (id=="ByteArray") { Vector<uint8_t> args; Error err = _parse_construct<uint8_t>(p_stream,args,line,r_err_str); if (err) return err; DVector<uint8_t> arr; { int len=args.size(); arr.resize(len); DVector<uint8_t>::Write w = arr.write(); for(int i=0;i<len;i++) { w[i]=args[i]; } } value=arr; return OK; } else if (id=="IntArray") { Vector<int32_t> args; Error err = _parse_construct<int32_t>(p_stream,args,line,r_err_str); if (err) return err; DVector<int32_t> arr; { int len=args.size(); arr.resize(len); DVector<int32_t>::Write w = arr.write(); for(int i=0;i<len;i++) { w[i]=int(args[i]); } } value=arr; return OK; } else if (id=="FloatArray") { Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; DVector<float> arr; { int len=args.size(); arr.resize(len); DVector<float>::Write w = arr.write(); for(int i=0;i<len;i++) { w[i]=args[i]; } } value=arr; return OK; } else if (id=="StringArray") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_PARENTHESIS_OPEN) { r_err_str="Expected '('"; return ERR_PARSE_ERROR; } Vector<String> cs; bool first=true; while(true) { if (!first) { get_token(p_stream,token,line,r_err_str); if (token.type==TK_COMMA) { //do none } else if (token.type==TK_PARENTHESIS_CLOSE) { break; } else { r_err_str="Expected ',' or ')'"; return ERR_PARSE_ERROR; } } get_token(p_stream,token,line,r_err_str); if (token.type!=TK_STRING) { r_err_str="Expected string"; return ERR_PARSE_ERROR; } first=false; cs.push_back(token.value); } DVector<String> arr; { int len=cs.size(); arr.resize(len); DVector<String>::Write w = arr.write(); for(int i=0;i<len;i++) { w[i]=cs[i]; } } value=arr; return OK; } else if (id=="Vector2Array") { Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; DVector<Vector2> arr; { int len=args.size()/2; arr.resize(len); DVector<Vector2>::Write w = arr.write(); for(int i=0;i<len;i++) { w[i]=Vector2(args[i*2+0],args[i*2+1]); } } value=arr; return OK; } else if (id=="Vector3Array") { Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; DVector<Vector3> arr; { int len=args.size()/3; arr.resize(len); DVector<Vector3>::Write w = arr.write(); for(int i=0;i<len;i++) { w[i]=Vector3(args[i*3+0],args[i*3+1],args[i*3+2]); } } value=arr; return OK; } else if (id=="ColorArray") { Vector<float> args; Error err = _parse_construct<float>(p_stream,args,line,r_err_str); if (err) return err; DVector<Color> arr; { int len=args.size()/4; arr.resize(len); DVector<Color>::Write w = arr.write(); for(int i=0;i<len;i++) { w[i]=Color(args[i*4+0],args[i*4+1],args[i*4+2],args[i*4+3]); } } value=arr; return OK; } else if (id=="key") { // compatibility with engine.cfg Vector<String> params; Error err = _parse_enginecfg(p_stream,params,line,r_err_str); if (err) return err; ERR_FAIL_COND_V(params.size()!=1 && params.size()!=2,ERR_PARSE_ERROR); int scode=0; if (params[0].is_numeric()) { scode=params[0].to_int(); if (scode < 10) { scode=KEY_0+scode; } } else scode=find_keycode(params[0]); InputEvent ie; ie.type=InputEvent::KEY; ie.key.scancode=scode; if (params.size()==2) { String mods=params[1]; if (mods.findn("C")!=-1) ie.key.mod.control=true; if (mods.findn("A")!=-1) ie.key.mod.alt=true; if (mods.findn("S")!=-1) ie.key.mod.shift=true; if (mods.findn("M")!=-1) ie.key.mod.meta=true; } value=ie; return OK; } else if (id=="mbutton") { // compatibility with engine.cfg Vector<String> params; Error err = _parse_enginecfg(p_stream,params,line,r_err_str); if (err) return err; ERR_FAIL_COND_V(params.size()!=2,ERR_PARSE_ERROR); InputEvent ie; ie.type=InputEvent::MOUSE_BUTTON; ie.device=params[0].to_int(); ie.mouse_button.button_index=params[1].to_int(); value=ie; return OK; } else if (id=="jbutton") { // compatibility with engine.cfg Vector<String> params; Error err = _parse_enginecfg(p_stream,params,line,r_err_str); if (err) return err; ERR_FAIL_COND_V(params.size()!=2,ERR_PARSE_ERROR); InputEvent ie; ie.type=InputEvent::JOYSTICK_BUTTON; ie.device=params[0].to_int(); ie.joy_button.button_index=params[1].to_int(); value=ie; return OK; } else if (id=="jaxis") { // compatibility with engine.cfg Vector<String> params; Error err = _parse_enginecfg(p_stream,params,line,r_err_str); if (err) return err; ERR_FAIL_COND_V(params.size()!=2,ERR_PARSE_ERROR); InputEvent ie; ie.type=InputEvent::JOYSTICK_MOTION; ie.device=params[0].to_int(); int axis=params[1].to_int(); ie.joy_motion.axis=axis>>1; ie.joy_motion.axis_value=axis&1?1:-1; value= ie; return OK; } else if (id=="img") { // compatibility with engine.cfg
void i_vti_v(RBlackbox& Res, DenseMatrix<Rationals >& M, DVector& den, Integer& detPrec) { detPrec=1; Rationals Q; int n = M.coldim(); //DVector denV(n,1); for (int i=0; i < den.size();++i) den[i]=1; for (int i=0; i < n; ++i) { for (int j=0; j <=i ; ++j) { Integer q_num =0; Integer q_den =1; for (int k=0; k < n; ++k) { Integer deno_ik, nume_ik, deno_jk, nume_jk, deno, nume; Q.get_den (deno_ik, M.getEntry(k,i)); Q.get_num (nume_ik, M.getEntry(k,i)); Q.get_den (deno_jk, M.getEntry(k,j)); Q.get_num (nume_jk, M.getEntry(k,j)); if (i==k) { nume_ik = deno_ik-nume_ik; } else { nume_ik = -nume_ik; } if (j==k) { nume_jk = deno_jk-nume_jk; } else { nume_jk = -nume_jk; } //cout << nume_ik << nume_jk; deno = deno_ik*deno_jk; nume = nume_ik*nume_jk; //cout << q_num << "/" << q_den << " " ; //cout << nume << "/" << deno << " " ; if (deno==q_den) q_num+=nume; else { if (nume != 0) { Integer g = gcd(q_den, deno); q_num = q_num*deno/g+nume*q_den/g; q_den = q_den*deno/g; } } //cout << q_num << "/" << q_den << " " ; } if (q_num != 0) { Quotient q(q_num,q_den); if (i!=j) { den[i]=lcm(den[i], q_den); den[j]=lcm(den[j], q_den); Res.setEntry(i,j,q); Res.setEntry(j,i,q); cout << i << " " << j << " " << q_num << "/" << q_den << "\n"; cout << j << " " << i << " " << q_num << "/" << q_den << "\n"; } else { den[i]=lcm(den[i], q_den); Res.setEntry(i,j,q); cout << i << " " << j << " " << q_num << "/" << q_den << "\n"; } } } } Integer d = 1; for (int i=0; i < den.size(); ++i) { detPrec *=den[i]; d = lcm(d, den[i]); } den[den.size()-1]=d; for (int i=den.size()-2; i >=0; --i) { den[i]=d*den[i+1]; } }
void TriangleMesh::create(const DVector<Vector3>& p_faces) { valid=false; int fc=p_faces.size(); ERR_FAIL_COND(!fc || ((fc%3) != 0)); fc/=3; triangles.resize(fc); bvh.resize(fc*3); //will never be larger than this (todo make better) DVector<BVH>::Write bw = bvh.write(); { //create faces and indices and base bvh //except for the Set for repeated triangles, everything //goes in-place. DVector<Vector3>::Read r = p_faces.read(); DVector<Triangle>::Write w = triangles.write(); Map<Vector3,int> db; for(int i=0;i<fc;i++) { Triangle&f=w[i]; const Vector3 *v=&r[i*3]; for(int j=0;j<3;j++) { int vidx=-1; Vector3 vs=v[j].snapped(0.0001); Map<Vector3,int>::Element *E=db.find(vs); if (E) { vidx=E->get(); } else { vidx=db.size(); db[vs]=vidx; } f.indices[j]=vidx; if (j==0) bw[i].aabb.pos=vs; else bw[i].aabb.expand_to(vs); } f.normal=Face3(r[i*3+0],r[i*3+1],r[i*3+2]).get_plane().get_normal(); bw[i].left=-1; bw[i].right=-1; bw[i].face_index=i; bw[i].center=bw[i].aabb.pos+bw[i].aabb.size*0.5; } vertices.resize(db.size()); DVector<Vector3>::Write vw = vertices.write(); for (Map<Vector3,int>::Element *E=db.front();E;E=E->next()) { vw[E->get()]=E->key(); } } DVector<BVH*> bwptrs; bwptrs.resize(fc); DVector<BVH*>::Write bwp = bwptrs.write(); for(int i=0;i<fc;i++) { bwp[i]=&bw[i]; } max_depth=0; int max_alloc=fc; int max=_create_bvh(bw.ptr(),bwp.ptr(),0,fc,1,max_depth,max_alloc); bw=DVector<BVH>::Write(); //clearup bvh.resize(max_alloc); //resize back valid=true; }
void generate_precRatMat(string& filename, RMatrix& M, DVector& den, Integer& denPrec) { int prec=10; denPrec = 1; ifstream is(filename.c_str(), std::ios::in); int m,n; char c; is >> m >> n; do is >> c; while (isspace (c)); if ((m > M.rowdim()) || (n > M.coldim())) { cout << m << " " << n << " " ; cout << "Wrong matrix size\n"; return; } cout << "Reading matrix\n"; den.resize(m,1); while (1) {//! @todo temp fix #if 0 while (is >> m) //temp fix if (m==0) break;//temp fix #endif is >> m;//temp fix is >> n; #if 0 cout << m << n << "\n"; long double x; is >> x; #endif char xstr[500]; char numstr[500]; #if 0 cout << x << " "; sprintf(xstr, "%100f", x); cout << xstr << " " ; is >> c; int i=0; while (c!= '\n') { xstr[i]=c; ++i; is >> c; if (i>=199) { xstr[i]=0; break; } } is >> c; #endif is.getline(xstr,500); Integer ten=1; if (strchr(xstr, '/') != NULL) { //cout << "xstr " << xstr << "\n"; //! @bug non reentrant strtok strcpy(numstr, strtok(xstr, "/")); char tenstr[500]; strcpy(tenstr, strtok(NULL, "/")); if (prec < strlen(tenstr)) { int cut = strlen(tenstr)-prec; tenstr[prec]=0; //c = numstr[strlen(numstr)-2]; numstr[strlen(numstr)-cut]=0;//temp round down } Integer tmp(tenstr); ten = tmp; //cout << numstr << "/" << ten << "\n"; } else { // cout << "xstr" << xstr << " " ; int i=0; int j=0; c=xstr[i]; ++i; while (isspace (c)) { if (i >=strlen(xstr)) break; c=xstr[i]; ++i; } if (c=='-') { numstr[j]=c;++j; if (i < strlen(xstr)) { c = xstr[i]; ++i; } } if (c=='0') { //cout << "zero"; if (i < strlen(xstr)) { c = xstr[i]; ++i; } } //else cout << " not 0" << c; while (strchr("0123456789",c) != NULL) { //cout << "number"; numstr[j]=c; ++j; if (i >=strlen(xstr)) break; c=xstr[i]; ++i; } if (c=='.') { if (i < strlen(xstr)) { c = xstr[i]; //cout << "c" << c ; ++i; while (strchr("0123456789",c) != NULL) { numstr[j]=c;++j; if (i >=strlen(xstr)) break; c=xstr[i]; ++i; } } else { cout << "wrong number format at ."; break; } } numstr[j]=0; //cout << "num" << numstr << " " ; size_t dplaces=0; int exp=0; j=0; c = xstr[j]; ++j; while (c != '.') { if (j >= strlen(xstr)) break; c = xstr[j]; ++j; } if (j < strlen(xstr)) { c = xstr[j]; ++j; while (c != 'e') { ++dplaces; ten *= 10; if (j >= strlen(xstr)) break; c = xstr[j]; ++j; } } if (j < strlen(xstr)) { sscanf(xstr+j, "%d", &exp); j=j-2;c = xstr[j]; while (c=='0') { ten/=10; --j; c = xstr[j]; } } dplaces -=exp; if (exp > 0) { for (int i=0; i < exp; ++i) ten /=10; } else if (exp < 0) { for (int i=0; i < exp; ++i) ten *=10; } //double nume = x * (double)ten; } Integer num (numstr); Integer g; #ifdef _LB_CONT_FR double epsi = 1/(double)ten*10; size_t s=10; continuedFractionIn(num, ten, epsi, s, ten); #endif //cout << m << " " << n << " " << num << "/" << ten << "\n"; g = gcd(num,ten); //g =1; Quotient q(num/g,ten/g); if ((m==0)&&(n==0)&&(num==0)) break;//temp fix //M.setEntry(m-1,n-1,q);//temp fix M.setEntry(m,n,q); den[m-1] = lcm(den[m-1],ten/g); } Integer d = 1; for (int i=0; i < den.size(); ++i) { denPrec *=den[i]; d = lcm(d, den[i]); } den[den.size()-1]=d; cout << d << "\n"; for (int i=den.size()-2; i >=0; --i) { den[i]=d*den[i+1]; cout << den[i] << "\n"; } }
Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ ERR_FAIL_COND_V(p_from->get_source_count()!=1,ERR_INVALID_PARAMETER); Ref<ResourceImportMetadata> from=p_from; String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0)); Ref<Sample> smp = ResourceLoader::load(src_path); ERR_FAIL_COND_V(smp.is_null(),ERR_CANT_OPEN); float rate = smp->get_mix_rate(); bool is16 = smp->get_format()==Sample::FORMAT_PCM16; int chans = smp->is_stereo()?2:1; int len = smp->get_length(); Sample::LoopFormat loop= smp->get_loop_format(); int loop_beg = smp->get_loop_begin(); int loop_end = smp->get_loop_end(); print_line("Input Sample: "); print_line("\tlen: "+itos(len)); print_line("\tchans: "+itos(chans)); print_line("\t16bits: "+itos(is16)); print_line("\trate: "+itos(rate)); print_line("\tloop: "+itos(loop)); print_line("\tloop begin: "+itos(loop_beg)); print_line("\tloop end: "+itos(loop_end)); Vector<float> data; data.resize(len*chans); { DVector<uint8_t> src_data = smp->get_data(); DVector<uint8_t>::Read sr = src_data.read(); for(int i=0;i<len*chans;i++) { float s=0; if (is16) { int16_t i16 = decode_uint16(&sr[i*2]); s=i16/32767.0; } else { int8_t i8 = sr[i]; s=i8/127.0; } data[i]=s; } } //apply frequency limit bool limit_rate = from->get_option("force/max_rate"); int limit_rate_hz = from->get_option("force/max_rate_hz"); if (limit_rate && rate > limit_rate_hz) { //resampleeee!!! int new_data_len = len * limit_rate_hz / rate; Vector<float> new_data; new_data.resize( new_data_len * chans ); for(int c=0;c<chans;c++) { for(int i=0;i<new_data_len;i++) { //simple cubic interpolation should be enough. float pos = float(i) * len / new_data_len; float mu = pos-Math::floor(pos); int ipos = int(Math::floor(pos)); float y0=data[MAX(0,ipos-1)*chans+c]; float y1=data[ipos*chans+c]; float y2=data[MIN(len-1,ipos+1)*chans+c]; float y3=data[MIN(len-1,ipos+2)*chans+c]; float mu2 = mu*mu; float a0 = y3 - y2 - y0 + y1; float a1 = y0 - y1 - a0; float a2 = y2 - y0; float a3 = y1; float res=(a0*mu*mu2+a1*mu2+a2*mu+a3); new_data[i*chans+c]=res; } } if (loop) { loop_beg=loop_beg*new_data_len/len; loop_end=loop_end*new_data_len/len; } data=new_data; rate=limit_rate_hz; len=new_data_len; } bool normalize = from->get_option("edit/normalize"); if (normalize) { float max=0; for(int i=0;i<data.size();i++) { float amp = Math::abs(data[i]); if (amp>max) max=amp; } if (max>0) { float mult=1.0/max; for(int i=0;i<data.size();i++) { data[i]*=mult; } } } bool trim = from->get_option("edit/trim"); if (trim && !loop) { int first=0; int last=(len*chans)-1; bool found=false; float limit = Math::db2linear(-30); for(int i=0;i<data.size();i++) { float amp = Math::abs(data[i]); if (!found && amp > limit) { first=i; found=true; } if (found && amp > limit) { last=i; } } first/=chans; last/=chans; if (first<last) { Vector<float> new_data; new_data.resize((last-first+1)*chans); for(int i=first*chans;i<=last*chans;i++) { new_data[i-first*chans]=data[i]; } data=new_data; len=data.size()/chans; } } bool make_loop = from->get_option("edit/loop"); if (make_loop && !loop) { loop=Sample::LOOP_FORWARD; loop_beg=0; loop_end=len; } int compression = from->get_option("compress/mode"); bool force_mono = from->get_option("force/mono"); if (force_mono && chans==2) { Vector<float> new_data; new_data.resize(data.size()/2); for(int i=0;i<len;i++) { new_data[i]=(data[i*2+0]+data[i*2+1])/2.0; } data=new_data; chans=1; } bool force_8_bit = from->get_option("force/8_bit"); if (force_8_bit) { is16=false; } DVector<uint8_t> dst_data; Sample::Format dst_format; if ( compression == _EditorSampleImportOptions::COMPRESS_MODE_RAM) { dst_format=Sample::FORMAT_IMA_ADPCM; if (chans==1) { _compress_ima_adpcm(data,dst_data); } else { print_line("INTERLEAAVE!"); //byte interleave Vector<float> left; Vector<float> right; int tlen = data.size()/2; left.resize(tlen); right.resize(tlen); for(int i=0;i<tlen;i++) { left[i]=data[i*2+0]; right[i]=data[i*2+1]; } DVector<uint8_t> bleft; DVector<uint8_t> bright; _compress_ima_adpcm(left,bleft); _compress_ima_adpcm(right,bright); int dl = bleft.size(); dst_data.resize( dl *2 ); DVector<uint8_t>::Write w=dst_data.write(); DVector<uint8_t>::Read rl=bleft.read(); DVector<uint8_t>::Read rr=bright.read(); for(int i=0;i<dl;i++) { w[i*2+0]=rl[i]; w[i*2+1]=rr[i]; } } // print_line("compressing ima-adpcm, resulting buffersize is "+itos(dst_data.size())+" from "+itos(data.size())); } else { dst_format=is16?Sample::FORMAT_PCM16:Sample::FORMAT_PCM8; dst_data.resize( data.size() * (is16?2:1)); { DVector<uint8_t>::Write w = dst_data.write(); int ds=data.size(); for(int i=0;i<ds;i++) { if (is16) { int16_t v = CLAMP(data[i]*32767,-32768,32767); encode_uint16(v,&w[i*2]); } else { int8_t v = CLAMP(data[i]*127,-128,127); w[i]=v; } } } } Ref<Sample> target; if (ResourceCache::has(p_path)) { target = Ref<Sample>( ResourceCache::get(p_path)->cast_to<Sample>() ); } else { target = smp; } target->create(dst_format,chans==2?true:false,len); target->set_data(dst_data); target->set_mix_rate(rate); target->set_loop_format(loop); target->set_loop_begin(loop_beg); target->set_loop_end(loop_end); from->set_source_md5(0,FileAccess::get_md5(src_path)); from->set_editor(get_name()); target->set_import_metadata(from); Error err = ResourceSaver::save(p_path,smp); return err; }
Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) { uint32_t type = f->get_32(); print_bl("find property of type: "+itos(type)); switch(type) { case VARIANT_NIL: { r_v=Variant(); } break; case VARIANT_BOOL: { r_v=bool(f->get_32()); } break; case VARIANT_INT: { r_v=int(f->get_32()); } break; case VARIANT_REAL: { r_v=f->get_real(); } break; case VARIANT_STRING: { r_v=get_unicode_string(); } break; case VARIANT_VECTOR2: { Vector2 v; v.x=f->get_real(); v.y=f->get_real(); r_v=v; } break; case VARIANT_RECT2: { Rect2 v; v.pos.x=f->get_real(); v.pos.y=f->get_real(); v.size.x=f->get_real(); v.size.y=f->get_real(); r_v=v; } break; case VARIANT_VECTOR3: { Vector3 v; v.x=f->get_real(); v.y=f->get_real(); v.z=f->get_real(); r_v=v; } break; case VARIANT_PLANE: { Plane v; v.normal.x=f->get_real(); v.normal.y=f->get_real(); v.normal.z=f->get_real(); v.d=f->get_real(); r_v=v; } break; case VARIANT_QUAT: { Quat v; v.x=f->get_real(); v.y=f->get_real(); v.z=f->get_real(); v.w=f->get_real(); r_v=v; } break; case VARIANT_AABB: { AABB v; v.pos.x=f->get_real(); v.pos.y=f->get_real(); v.pos.z=f->get_real(); v.size.x=f->get_real(); v.size.y=f->get_real(); v.size.z=f->get_real(); r_v=v; } break; case VARIANT_MATRIX32: { Matrix32 v; v.elements[0].x=f->get_real(); v.elements[0].y=f->get_real(); v.elements[1].x=f->get_real(); v.elements[1].y=f->get_real(); v.elements[2].x=f->get_real(); v.elements[2].y=f->get_real(); r_v=v; } break; case VARIANT_MATRIX3: { Matrix3 v; v.elements[0].x=f->get_real(); v.elements[0].y=f->get_real(); v.elements[0].z=f->get_real(); v.elements[1].x=f->get_real(); v.elements[1].y=f->get_real(); v.elements[1].z=f->get_real(); v.elements[2].x=f->get_real(); v.elements[2].y=f->get_real(); v.elements[2].z=f->get_real(); r_v=v; } break; case VARIANT_TRANSFORM: { Transform v; v.basis.elements[0].x=f->get_real(); v.basis.elements[0].y=f->get_real(); v.basis.elements[0].z=f->get_real(); v.basis.elements[1].x=f->get_real(); v.basis.elements[1].y=f->get_real(); v.basis.elements[1].z=f->get_real(); v.basis.elements[2].x=f->get_real(); v.basis.elements[2].y=f->get_real(); v.basis.elements[2].z=f->get_real(); v.origin.x=f->get_real(); v.origin.y=f->get_real(); v.origin.z=f->get_real(); r_v=v; } break; case VARIANT_COLOR: { Color v; v.r=f->get_real(); v.g=f->get_real(); v.b=f->get_real(); v.a=f->get_real(); r_v=v; } break; case VARIANT_IMAGE: { uint32_t encoding = f->get_32(); if (encoding==IMAGE_ENCODING_EMPTY) { r_v=Variant(); break; } else if (encoding==IMAGE_ENCODING_RAW) { uint32_t width = f->get_32(); uint32_t height = f->get_32(); uint32_t mipmaps = f->get_32(); uint32_t format = f->get_32(); Image::Format fmt; switch(format) { case IMAGE_FORMAT_GRAYSCALE: { fmt=Image::FORMAT_GRAYSCALE; } break; case IMAGE_FORMAT_INTENSITY: { fmt=Image::FORMAT_INTENSITY; } break; case IMAGE_FORMAT_GRAYSCALE_ALPHA: { fmt=Image::FORMAT_GRAYSCALE_ALPHA; } break; case IMAGE_FORMAT_RGB: { fmt=Image::FORMAT_RGB; } break; case IMAGE_FORMAT_RGBA: { fmt=Image::FORMAT_RGBA; } break; case IMAGE_FORMAT_INDEXED: { fmt=Image::FORMAT_INDEXED; } break; case IMAGE_FORMAT_INDEXED_ALPHA: { fmt=Image::FORMAT_INDEXED_ALPHA; } break; case IMAGE_FORMAT_BC1: { fmt=Image::FORMAT_BC1; } break; case IMAGE_FORMAT_BC2: { fmt=Image::FORMAT_BC2; } break; case IMAGE_FORMAT_BC3: { fmt=Image::FORMAT_BC3; } break; case IMAGE_FORMAT_BC4: { fmt=Image::FORMAT_BC4; } break; case IMAGE_FORMAT_BC5: { fmt=Image::FORMAT_BC5; } break; case IMAGE_FORMAT_PVRTC2: { fmt=Image::FORMAT_PVRTC2; } break; case IMAGE_FORMAT_PVRTC2_ALPHA: { fmt=Image::FORMAT_PVRTC2_ALPHA; } break; case IMAGE_FORMAT_PVRTC4: { fmt=Image::FORMAT_PVRTC4; } break; case IMAGE_FORMAT_PVRTC4_ALPHA: { fmt=Image::FORMAT_PVRTC4_ALPHA; } break; case IMAGE_FORMAT_ETC: { fmt=Image::FORMAT_ETC; } break; case IMAGE_FORMAT_CUSTOM: { fmt=Image::FORMAT_CUSTOM; } break; default: { ERR_FAIL_V(ERR_FILE_CORRUPT); } } uint32_t datalen = f->get_32(); DVector<uint8_t> imgdata; imgdata.resize(datalen); DVector<uint8_t>::Write w = imgdata.write(); f->get_buffer(w.ptr(),datalen); _advance_padding(datalen); w=DVector<uint8_t>::Write(); r_v=Image(width,height,mipmaps,fmt,imgdata); } else { //compressed DVector<uint8_t> data; data.resize(f->get_32()); DVector<uint8_t>::Write w = data.write(); f->get_buffer(w.ptr(),data.size()); w = DVector<uint8_t>::Write(); Image img; if (encoding==IMAGE_ENCODING_LOSSY && Image::lossy_unpacker) { img = Image::lossy_unpacker(data); } else if (encoding==IMAGE_ENCODING_LOSSLESS && Image::lossless_unpacker) { img = Image::lossless_unpacker(data); } _advance_padding(data.size()); r_v=img; } } break; case VARIANT_NODE_PATH: { Vector<StringName> names; Vector<StringName> subnames; StringName property; bool absolute; int name_count = f->get_16(); uint32_t subname_count = f->get_16(); absolute=subname_count&0x8000; subname_count&=0x7FFF; for(int i=0;i<name_count;i++) names.push_back(string_map[f->get_32()]); for(uint32_t i=0;i<subname_count;i++) subnames.push_back(string_map[f->get_32()]); property=string_map[f->get_32()]; NodePath np = NodePath(names,subnames,absolute,property); //print_line("got path: "+String(np)); r_v=np; } break; case VARIANT_RID: { r_v=f->get_32(); } break; case VARIANT_OBJECT: { uint32_t type=f->get_32(); switch(type) { case OBJECT_EMPTY: { //do none } break; case OBJECT_INTERNAL_RESOURCE: { uint32_t index=f->get_32(); String path = res_path+"::"+itos(index); RES res = ResourceLoader::load(path); if (res.is_null()) { WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data()); } r_v=res; } break; case OBJECT_EXTERNAL_RESOURCE: { String type = get_unicode_string(); String path = get_unicode_string(); if (path.find("://")==-1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path path=Globals::get_singleton()->localize_path(res_path.get_base_dir()+"/"+path); } RES res=ResourceLoader::load(path,type); if (res.is_null()) { WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data()); } r_v=res; } break; default: { ERR_FAIL_V(ERR_FILE_CORRUPT); } break; } } break; case VARIANT_INPUT_EVENT: { } break; case VARIANT_DICTIONARY: { uint32_t len=f->get_32(); Dictionary d(len&0x80000000); //last bit means shared len&=0x7FFFFFFF; for(uint32_t i=0;i<len;i++) { Variant key; Error err = parse_variant(key); ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT); Variant value; err = parse_variant(value); ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT); d[key]=value; } r_v=d; } break; case VARIANT_ARRAY: { uint32_t len=f->get_32(); Array a(len&0x80000000); //last bit means shared len&=0x7FFFFFFF; a.resize(len); for(uint32_t i=0;i<len;i++) { Variant val; Error err = parse_variant(val); ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT); a[i]=val; } r_v=a; } break; case VARIANT_RAW_ARRAY: { uint32_t len = f->get_32(); DVector<uint8_t> array; array.resize(len); DVector<uint8_t>::Write w = array.write(); f->get_buffer(w.ptr(),len); _advance_padding(len); w=DVector<uint8_t>::Write(); r_v=array; } break; case VARIANT_INT_ARRAY: { uint32_t len = f->get_32(); DVector<int> array; array.resize(len); DVector<int>::Write w = array.write(); f->get_buffer((uint8_t*)w.ptr(),len*4); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr=(uint32_t*)w.ptr(); for(int i=0;i<len;i++) { ptr[i]=BSWAP32(ptr[i]); } } #endif w=DVector<int>::Write(); r_v=array; } break; case VARIANT_REAL_ARRAY: { uint32_t len = f->get_32(); DVector<real_t> array; array.resize(len); DVector<real_t>::Write w = array.write(); f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr=(uint32_t*)w.ptr(); for(int i=0;i<len;i++) { ptr[i]=BSWAP32(ptr[i]); } } #endif w=DVector<real_t>::Write(); r_v=array; } break; case VARIANT_STRING_ARRAY: { uint32_t len = f->get_32(); DVector<String> array; array.resize(len); DVector<String>::Write w = array.write(); for(uint32_t i=0;i<len;i++) w[i]=get_unicode_string(); w=DVector<String>::Write(); r_v=array; } break; case VARIANT_VECTOR2_ARRAY: { uint32_t len = f->get_32(); DVector<Vector2> array; array.resize(len); DVector<Vector2>::Write w = array.write(); if (sizeof(Vector2)==8) { f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)*2); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr=(uint32_t*)w.ptr(); for(int i=0;i<len*2;i++) { ptr[i]=BSWAP32(ptr[i]); } } #endif } else { ERR_EXPLAIN("Vector2 size is NOT 8!"); ERR_FAIL_V(ERR_UNAVAILABLE); } w=DVector<Vector2>::Write(); r_v=array; } break; case VARIANT_VECTOR3_ARRAY: { uint32_t len = f->get_32(); DVector<Vector3> array; array.resize(len); DVector<Vector3>::Write w = array.write(); if (sizeof(Vector3)==12) { f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)*3); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr=(uint32_t*)w.ptr(); for(int i=0;i<len*3;i++) { ptr[i]=BSWAP32(ptr[i]); } } #endif } else { ERR_EXPLAIN("Vector3 size is NOT 12!"); ERR_FAIL_V(ERR_UNAVAILABLE); } w=DVector<Vector3>::Write(); r_v=array; } break; case VARIANT_COLOR_ARRAY: { uint32_t len = f->get_32(); DVector<Color> array; array.resize(len); DVector<Color>::Write w = array.write(); if (sizeof(Color)==16) { f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)*4); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr=(uint32_t*)w.ptr(); for(int i=0;i<len*4;i++) { ptr[i]=BSWAP32(ptr[i]); } } #endif } else { ERR_EXPLAIN("Color size is NOT 16!"); ERR_FAIL_V(ERR_UNAVAILABLE); } w=DVector<Color>::Write(); r_v=array; } break; default: { ERR_FAIL_V(ERR_FILE_CORRUPT); } break; } return OK; //never reach anyway }