/* * Source code of OpenMetaverse is used in part. * * see also http://openmetaverse.org/ * see also OpenMetaverse.Primitive.TextureEntry Class */ /* * Copyright (c) 2007-2009, openmetaverse.org * All rights reserved. * * - Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Neither the name of the openmetaverse.org nor the names * of its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "PrimShape.h" using namespace jbxl; static const std::string _PrimProfType[PRIM_PROF_TYPE_NUM] = { PRIM_PROF_CIRCLE_STR, PRIM_PROF_SQUARE_STR, PRIM_PROF_ISOTRIANGLE_STR, PRIM_PROF_EQLTRIANGLE_STR, PRIM_PROF_RGTTRIANGLE_STR, PRIM_PROF_HALFCIRCLE_STR }; // static const std::string _PrimHoleType[PRIM_HOLE_TYPE_NUM] = { PRIM_HOLE_SAME_STR, PRIM_HOLE_CIRCLE_STR, PRIM_HOLE_SQUARE_STR, PRIM_HOLE_TRIANGLE_STR }; // static const std::string _PrimBumpMapUUID[PRIM_BUMPMAP_NUM] = { "00000000-0000-0000-0000-000000000000", // Brightness "ffffffff-ffff-ffff-ffff-ffffffffffff", // Darkness "058c75c0-a0d5-f2f8-43f3-e9699a89c2fc", // woodgrain "6c9fa78a-1c69-2168-325b-3e03ffa348ce", // bark "b8eed5f0-64b7-6e12-b67f-43fa8e773440", // briks "9deab416-9c63-78d6-d558-9a156f12044c", // checker "db9d39ec-a896-c287-1ced-64566217021e", // concrete "f2d7b6f6-4200-1e9a-fd5b-96459e950f94", // crustytile "d9258671-868f-7511-c321-7baef9e948a4", // cutstone "d21e44ca-ff1c-a96e-b2ef-c0753426b7d9", // discs "4726f13e-bd07-f2fb-feb0-bfa2ac58ab61", // gravel "e569711a-27c2-aad4-9246-0c910239a179", // petridish "073c9723-540c-5449-cdd4-0e87fdc159e3", // siding "ae874d1a-93ef-54fb-5fd3-eb0cb156afc0", // stonetile "92e66e00-f56f-598a-7997-048aa64cde18", // stucco "83b77fc6-10b4-63ec-4de7-f40629f238c5", // suction "735198cf-6ea0-2550-e222-21d3c6a341ae" // weave }; ////////////////////////////////////////////////////////////////////////////////////////// // void PrimBaseShape::init(void) { ObjectName = init_Buffer(); PCode = PRIM_PCODE_PRIM; State = 0; ProfileCurve = PRIM_PROF_CIRCLE; ProfileBegin = 0; ProfileEnd = 0; ProfileHollow = 0; PathCurve = PRIM_PATH_LINE; PathBegin = 0; PathEnd = 0; PathRadiusOffset= 0; PathRevolutions = 0; PathScaleX = 100; PathScaleY = 100; PathShearX = 0; PathShearY = 0; PathSkew = 0; PathTaperX = 0; PathTaperY = 0; PathTwist = 0; PathTwistBegin = 0; ProfileShape = PRIM_PROF_CIRCLE; // same ProfileCurve? HollowShape = PRIM_HOLE_SAME; SculptType = 0; SculptTexture = init_Buffer(); SculptEntry = false; ObjFlags = init_Buffer(); // AffineTrans は自身のコンストラクタで初期化される. for (int i=0; i* base) { if (xml==NULL) return; init(); // Object Name char* objname = get_xml_str_content_bystr(xml, ""); if (objname!=NULL) ObjectName = make_Buffer_bystr(objname); PCode = get_xml_int_content_bystr(xml, ""); State = get_xml_int_content_bystr(xml, ""); // ProfileCurve = get_xml_int_content_bystr(xml, ""); ProfileBegin = get_xml_int_content_bystr(xml, ""); ProfileEnd = get_xml_int_content_bystr(xml, ""); ProfileHollow = get_xml_int_content_bystr(xml, ""); PathCurve = get_xml_int_content_bystr(xml, ""); PathBegin = get_xml_int_content_bystr(xml, ""); PathEnd = get_xml_int_content_bystr(xml, ""); PathScaleX = get_xml_int_content_bystr(xml, ""); PathScaleY = get_xml_int_content_bystr(xml, ""); PathShearX = get_xml_int_content_bystr(xml, ""); PathShearY = get_xml_int_content_bystr(xml, ""); PathSkew = get_xml_int_content_bystr(xml, ""); PathTaperX = get_xml_int_content_bystr(xml, ""); PathTaperY = get_xml_int_content_bystr(xml, ""); PathTwist = get_xml_int_content_bystr(xml, ""); PathTwistBegin = get_xml_int_content_bystr(xml, ""); PathRadiusOffset= get_xml_int_content_bystr(xml, ""); PathRevolutions = get_xml_int_content_bystr(xml, ""); char* cntnt = get_xml_str_content_bystr(xml, ""); if (cntnt!=NULL) { for (int i=0; i"); if (cntnt!=NULL) { for (int i=0; i"); char* sculptTex = get_xml_str_content_bystr(xml, ""); SculptTexture = make_Buffer_bystr(sculptTex); char* entry = get_xml_str_content_bystr(xml, ""); if (!strcasecmp(entry, "true")) SculptEntry = true; else SculptEntry = false; // if (PCode==PRIM_PCODE_AVATAR) { // } else if (PCode==PRIM_PCODE_GRASS) { // } else if (PCode==PRIM_PCODE_PARTICLE) { // } else if (PCode==PRIM_PCODE_NEWTREE || PCode==PRIM_PCODE_TREE) { // Tree // State が木の種類を表す } // Texture Entry GetTextureEntry(xml); // Extra Params GetExtraParams(xml); int stype = SculptType & 0x07; if (SculptEntry && stype"); double gposy = (double)get_xml_float_content_bystr(xml, ""); double gposz = (double)get_xml_float_content_bystr(xml, ""); double oposx = (double)get_xml_float_content_bystr(xml, ""); double oposy = (double)get_xml_float_content_bystr(xml, ""); double oposz = (double)get_xml_float_content_bystr(xml, ""); if (base!=NULL) { affineTrans.shift.set(oposx, oposy, oposz); affineTrans.shift = base->execRotate(affineTrans.shift); affineTrans.shift = affineTrans.shift + Vector(gposx, gposy, gposz); } else { affineTrans.shift.set(gposx+oposx, gposy+oposy, gposz+oposz); } double rotx = (double)get_xml_float_content_bystr(xml, ""); double roty = (double)get_xml_float_content_bystr(xml, ""); double rotz = (double)get_xml_float_content_bystr(xml, ""); double rots = (double)get_xml_float_content_bystr(xml, ""); affineTrans.rotate.set(rots, rotx, roty, rotz); if (base!=NULL) { affineTrans.rotate = base->rotate*affineTrans.rotate; } double sclx = (double)get_xml_float_content_bystr(xml, ""); double scly = (double)get_xml_float_content_bystr(xml, ""); double sclz = (double)get_xml_float_content_bystr(xml, ""); affineTrans.scale.set(sclx, scly, sclz); affineTrans.computeMatrix(false); // Flags "Physics Phantom TemporaryOnRez" char* objflags = get_xml_str_content_bystr(xml, ""); ObjFlags = make_Buffer_bystr(objflags); /* DEBUG_MODE { PRINT_MESG("[DEBUG INFO] in PrimBaseShape::GetBaseParamFromXML\n"); PrintBaseParam(); for (int i=0; i"); if (texttag!=NULL) { int size; uByte* textdata = decode_base64(texttag->ldat.key.buf, &size); /* DEBUG_MODE { PRINT_MESG("================================================================================== \n"); fdump(stderr, textdata, size); PRINT_MESG("================================================================================== \n"); }*/ // if (textdata!=NULL) { /////////////////////////////////////////////////////////////// // Default Entry. MaterialParam param = GetDefaultTextureEntry(textdata, size); for (int i=0; i0) materialName[i] = dup_Buffer(materialName[0]); } param.free(); // uByte* end = textdata + size - 1; uByte* ptr = textdata; int facetBits, fieldSize; // Texture ptr += 16; // default値の読み飛ばし while (ptr>6); materialParam[facet].setShininess(specular/3.0f); int bright = (int)((material & 0x20)>>5); // 0 or 1 if (bright==1) materialParam[facet].setBright(1.0f); int bumpno = (int)(material & 0x1f); if (bumpno>0 && bumpno<=PRIM_BUMPMAP_NUM) { materialParam[facet].setBumpMapName(_PrimBumpMapUUID[bumpno-1].c_str()); } } } ptr++; } // Media ptr++; // default値の読み飛ばし while (ptr>6); param.setShininess(specular/3.0f); int bright = (int)((material & 0x20)>>5); // 0 or 1 if (bright==1) param.setBright(1.0f); int bumpno = (int)(material & 0x1f); if (bumpno>0 && bumpno<=PRIM_BUMPMAP_NUM) { param.setBumpMapName(_PrimBumpMapUUID[bumpno-1].c_str()); } ptr++; while (ptr"); if (prmstag!=NULL) { int size; uByte* prmsdata = decode_base64(prmstag->ldat.key.buf, &size); /* DEBUG_MODE { PRINT_MESG("==================================================================================\n"); fdump(stderr, prmsdata, size); PRINT_MESG("==================================================================================\n"); }*/ int pos = 0; uByte* ptr = prmsdata; if (ptr!=NULL) { if (*ptr!=0x00) { pos++; unsigned short type = (unsigned short)(*((unsigned short*)(ptr+pos))); // if (type==16) { // 0x0010 Flexible pos += 2; int len = (int)(*((int*)(ptr+pos))); // // not implemented // pos += len + 4; if (pos+1SpecColor" #define SPEC_COLOR_TAG_G "SpecColor" #define SPEC_COLOR_TAG_B "SpecColor" #define SPEC_COLOR_TAG_A "SpecColor" // void PrimBaseShape::GetMaterialParams(tList* resourceList) { if (resourceList==NULL) return; for (int i=0; iDiffuseAlphaMode")); materialParam[i].setAlphaCutoff(get_xml_int_content_bystr(xml, "AlphaMaskCutoff")/255.0); materialParam[i].setGlossiness (get_xml_int_content_bystr(xml, "SpecExp")/255.0); materialParam[i].setEnvironment(get_xml_int_content_bystr(xml, "EnvIntensity")/255.0); // double colorR = get_xml_int_content_bystr(xml, SPEC_COLOR_TAG_R)/255.0; double colorG = get_xml_int_content_bystr(xml, SPEC_COLOR_TAG_G)/255.0; double colorB = get_xml_int_content_bystr(xml, SPEC_COLOR_TAG_B)/255.0; double colorA = get_xml_int_content_bystr(xml, SPEC_COLOR_TAG_A)/255.0; if (colorR==0.0) colorR = MTRL_DEFAULT_COLOR; if (colorG==0.0) colorG = MTRL_DEFAULT_COLOR; if (colorB==0.0) colorB = MTRL_DEFAULT_COLOR; materialParam[i].specmap.setColor(colorR, colorG, colorB, colorA); char* specmap = get_xml_str_content_bystr(xml, "SpecMap"); if (specmap!=NULL && strcmp(specmap, "00000000-0000-0000-0000-000000000000")) { materialParam[i].specmap.setName(specmap); materialParam[i].specmap.setShiftU(get_xml_int_content_bystr(xml, "SpecOffsetX") /10000.0); materialParam[i].specmap.setShiftV(get_xml_int_content_bystr(xml, "SpecOffsetY") /10000.0); materialParam[i].specmap.setScaleU(get_xml_int_content_bystr(xml, "SpecRepeatX") /10000.0); materialParam[i].specmap.setScaleV(get_xml_int_content_bystr(xml, "SpecRepeatY") /10000.0); materialParam[i].specmap.setRotate(get_xml_int_content_bystr(xml, "SpecRotation")/10000.0); } // char* bumpmap = get_xml_str_content_bystr(xml, "NormMap"); if (bumpmap!=NULL && strcmp(bumpmap, "00000000-0000-0000-0000-000000000000")) { materialParam[i].bumpmap.setName(bumpmap); materialParam[i].bumpmap.setShiftU(get_xml_int_content_bystr(xml, "NormOffsetX") /10000.0); materialParam[i].bumpmap.setShiftV(get_xml_int_content_bystr(xml, "NormOffsetY") /10000.0); materialParam[i].bumpmap.setScaleU(get_xml_int_content_bystr(xml, "NormRepeatX") /10000.0); materialParam[i].bumpmap.setScaleV(get_xml_int_content_bystr(xml, "NormRepeatY") /10000.0); materialParam[i].bumpmap.setRotate(get_xml_int_content_bystr(xml, "NormRotation")/10000.0); } // materialParam[i].enable = true; del_xml(&xml); } } } } return; } // void PrimBaseShape::PrintTextureEntry(void) { PRINT_MESG("[DEBUG INFO] in PrimBaseShape::PrintTextureEntry\n"); for (int i=0; i=0 && n=0 && n"); int count = count_tList(lp); if (count==0) return NULL; PrimBaseShape* shapes = (PrimBaseShape*)malloc(count*sizeof(PrimBaseShape)); if (shapes==NULL) return NULL; AffineTrans base; // ROOTプリムのアフィン変換 int n = 0; while (lp!=NULL) { PrimBaseShape rparam; if (n==0) { // 最初の(ROOT)プリム rparam.GetBaseParamFromXML(lp->altp, NULL); base.dup(rparam.affineTrans); } else { // 子プリム rparam.GetBaseParamFromXML(lp->altp, &base); } rparam.GetMaterialParams(rsclist); shapes[n].dup(rparam); /////////////////////////////////////////// //DEBUG_MODE rparam.PrintTextureEntry(); /////////////////////////////////////////// rparam.free(); lp = lp->next; n++; } base.free(); if (sno!=NULL) *sno = count; return shapes; } ////////////////////////////////////////////////////////////////////////////////////////// // PrimShapeParam // void PrimShapeParam::init(void) { objectName = init_Buffer(); pCode = PRIM_PCODE_PRIM; state = 0; profCurve = PRIM_PROF_CIRCLE; pathCurve = PRIM_PATH_LINE; hollowType = PRIM_HOLE_SAME; profBegin = 0.0; profEnd = 1.0; profHollow = 0.0; pathBegin = 0.0; pathEnd = 1.0; pathScaleX = 1.0; pathScaleY = 0.25; pathShearX = 0.0; pathShearY = 0.0; pathTaperX = 0.0; pathTaperY = 0.0; pathTwistBegin = 0.0; pathTwistEnd = 0.0; pathSkew = 0.0; pathRadius = 0.0; pathRevol = 1.0; sculptType = 0; sculptTexture = init_Buffer(); sculptEntry = false; objFlags = init_Buffer(); // AffineTrans は自身のコンストラクタで初期化される. for (int i=0; i0.95f) profHollow = 0.95; hollowType = shape.HollowShape; pathBegin = shape.PathBegin*PRIM_CUT_QUANTA; pathEnd = 1.0f - shape.PathEnd*PRIM_CUT_QUANTA; pathScaleX = 2.0f - shape.PathScaleX*PRIM_SCALE_QUANTA; pathScaleY = 2.0f - shape.PathScaleY*PRIM_SCALE_QUANTA; // Taper pathTaperX = shape.PathTaperX*PRIM_TAPER_QUANTA; pathTaperY = shape.PathTaperY*PRIM_TAPER_QUANTA; if (pathCurve==PRIM_PATH_LINE || pathCurve==PRIM_PATH_FLEXIBLE) { // by Fumi.Iseki for OAR 0.8 pathTaperX = 1.0f - pathScaleX; pathTaperY = 1.0f - pathScaleY; } pathShearX = shape.PathShearX < 128 ? (double)shape.PathShearX : shape.PathShearX-256.0; pathShearY = shape.PathShearY < 128 ? (double)shape.PathShearY : shape.PathShearY-256.0; pathShearX *= PRIM_SHEAR_QUANTA; pathShearY *= PRIM_SHEAR_QUANTA; pathTwistBegin = shape.PathTwistBegin*PRIM_SCALE_QUANTA*PI2; // Radian pathTwistEnd = shape.PathTwist*PRIM_SCALE_QUANTA*PI2; // Radian pathRadius = shape.PathRadiusOffset*PRIM_SCALE_QUANTA; pathSkew = shape.PathSkew*PRIM_SCALE_QUANTA; pathRevol = shape.PathRevolutions*PRIM_REV_QUANTA + 1.0f; sculptType = shape.SculptType; sculptTexture = dup_Buffer(shape.SculptTexture); sculptEntry = shape.SculptEntry; objFlags = dup_Buffer(shape.ObjFlags); affineTrans.free(); affineTrans.dup(shape.affineTrans); affineTrans.shift.set(affineTrans.shift.x, affineTrans.shift.y, affineTrans.shift.z); for (int i=0; i