void TMXLayer::parseInternalProperties() { // if cc_vertex=automatic, then tiles will be rendered using vertexz auto vertexz = getProperty("cc_vertexz"); if (!vertexz.isNull()) { std::string vertexZStr = vertexz.asString(); // If "automatic" is on, then parse the "cc_alpha_func" too if (vertexZStr == "automatic") { _useAutomaticVertexZ = true; auto alphaFuncVal = getProperty("cc_alpha_func"); float alphaFuncValue = alphaFuncVal.asFloat(); setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST)); GLint alphaValueLocation = glGetUniformLocation(getShaderProgram()->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE); // NOTE: alpha test shader is hard-coded to use the equivalent of a glAlphaFunc(GL_GREATER) comparison // use shader program to set uniform getShaderProgram()->use(); getShaderProgram()->setUniformLocationWith1f(alphaValueLocation, alphaFuncValue); CHECK_GL_ERROR_DEBUG(); } else { _vertexZvalue = vertexz.asInt(); } } }
std::ostream& value(const ast::types::abstract::Value& value) { const boost::regex esc("\n"); const std::string rep("\\\\n"); type(value.type()); stream << " "; switch(value) { case ast::types::Bool: stream << asBool(value).value; break; case ast::types::Float32: stream << asFloat(value).value; break; case ast::types::Int32: stream << asInt(value).value; break; case ast::types::String: stream << "\"" << boost::regex_replace(asString(value).value, esc, rep, boost::match_default | boost::format_sed) << "\""; break; case ast::types::Void: stream << "()"; break; default: stream << " ??"; } return stream; }
// get the value as time QTime KCValue::asTime(const KCCalculationSettings* settings) const { Q_UNUSED(settings); QTime dt; const int days = asInteger(); const int msecs = qRound(numToDouble(asFloat() - double(days)) * 86400000.0); // 24*60*60*1000 dt = dt.addMSecs(msecs); return dt; }
// get the value as date/time QDateTime KCValue::asDateTime(const KCCalculationSettings* settings) const { QDateTime datetime(settings->referenceDate(), QTime(), Qt::UTC); const int days = asInteger(); const int msecs = qRound((numToDouble(asFloat() - double(days))) * 86400000.0); // 24*60*60*1000 datetime = datetime.addDays(days); datetime = datetime.addMSecs(msecs); return datetime; }
TriState Value::asTriState() const { switch (opcode()) { case Const32: return triState(!!asInt32()); case Const64: return triState(!!asInt64()); case ConstDouble: // Use "!= 0" to really emphasize what this mean with respect to NaN and such. return triState(asDouble() != 0); case ConstFloat: return triState(asFloat() != 0.); default: return MixedTriState; } }
void animation_converter::run() { for (auto it = root_.begin(); it != root_.end(); ++it) { std::string model_name = it.key().asString(); auto& value = *it; std::unordered_map<int, bone> bone_hierachy; auto skeleton = value["skeleton"]; if (skeleton.isNull()) { throw std::runtime_error("no skeleton data in " + model_name); } for (auto& b : skeleton) { bone bn; auto id = b["id"]; if (id.isNull()) { throw std::runtime_error("no id attribute in bone data of " + model_name); } bn.id = id.asInt(); auto parent = b["parent"]; if (parent.isNull()) { bn.parent = -1; } else { bn.parent = parent.asInt(); } auto translation = b["translation"]; if (translation.isNull()) { throw std::runtime_error("no translation attribute in bone data of " + model_name); } if (translation.size() != 3) { throw std::runtime_error("translation attribute has not the apropriate size in " + model_name); } auto trans = glm::vec3{translation[0].asFloat(), translation[1].asFloat(), translation[2].asFloat()}; auto rotation = b["rotation"]; if (rotation.isNull()) { throw std::runtime_error("no rotation attribute in bone data of " + model_name); } if (rotation.size() != 4) { throw std::runtime_error("rotation attribute has not the apropriate size in " + model_name); } auto rot = glm::quat{rotation[0].asFloat(), rotation[1].asFloat(), rotation[2].asFloat(), rotation[3].asFloat()}; rot = glm::normalize(rot); auto transform = glm::toMat4(rot); transform[3].x = trans.x; transform[3].y = trans.y; transform[3].z = trans.z; static auto offset = glm::angleAxis(glm::radians(-90.f), glm::vec3{1.f, 0.f, 0.f}); static auto offset_matrix = glm::toMat4(offset); static auto offset_matrix_t = glm::transpose(offset_matrix); transform = offset_matrix * transform * offset_matrix_t; bn.relative_transform = transform; bn.absolute_transform = transform; bone_hierachy.insert(std::make_pair(bn.id, bn)); } /* for (auto i = 0; i < bone_hierachy.size(); ++i) { auto parent = bone_hierachy[i].parent; if (parent != -1) { bone_hierachy[i].absolute_transform = bone_hierachy[parent].absolute_transform * bone_hierachy[i].absolute_transform; } } */ std::stack<int32_t> traversal; traversal.push(0); while (!traversal.empty()) { auto current = traversal.top(); traversal.pop(); auto node = value["bone_hierachy"][std::to_string(current)]; if (node.isNull()) { continue; } for (auto& child : node) { auto c = child.asInt(); traversal.push(c); bone_hierachy[c].absolute_transform = bone_hierachy[current].absolute_transform * bone_hierachy[c].absolute_transform; } } std::vector<bone> bones; for (auto i = 0ul; i < bone_hierachy.size(); ++i) { bone_hierachy[i].absolute_transform = glm::inverse(bone_hierachy[i].absolute_transform); bones.emplace_back(bone_hierachy[i]); } auto animations = value["animations"]; if (animations.isNull()) { throw std::runtime_error("no animation data in " + model_name); } header h; h.bone_count = bones.size(); h.animation_count = animations.size(); std::string output_file = output_path_ + "anims/" + model_name + ".skl"; std::ofstream output(output_file, std::ios::binary | std::ios::trunc); if (!output.is_open()) { throw std::runtime_error("could not open output file " + output_file); } std::vector<animation> anims; std::vector<track> all_tracks; std::vector<translation_keyframe> all_tkeys; std::vector<rotation_keyframe> all_qkeys; std::vector<scale_keyframe> all_skeys; for (auto at = animations.begin(); at != animations.end(); ++at) { animation a; a.name = at.key().asString(); auto& anim = *at; auto length = anim["length"]; if (length.isNull()) { throw std::runtime_error("animation " + a.name + " has no length attribute"); } a.length = length.asFloat(); auto tracks = anim["tracks"]; if (tracks.isNull()) { throw std::runtime_error("animation " + a.name + " has no tracks"); } a.track_count = tracks.size(); anims.emplace_back(a); for (auto tt = tracks.begin(); tt != tracks.end(); ++tt) { auto bone_name = tt.key().asString(); auto& anim_track = *tt; auto bone_id = anim_track["id"]; if (bone_id.isNull()) { throw std::runtime_error("track " + bone_name + " in animation " + a.name + " has no id"); } auto& b = bone_hierachy[bone_id.asInt()]; track t; t.id = b.id; t.parent = b.parent; auto tkeys = anim_track["location"]; if (tkeys.isNull()) { throw std::runtime_error("track " + bone_name + " in animation " + a.name + " has no translation keys"); } t.tkey_count = tkeys.size(); auto qkeys = anim_track["rotation_quaternion"]; if (qkeys.isNull()) { throw std::runtime_error("track " + bone_name + " in animation " + a.name + " has no rotation keys"); } t.qkey_count = qkeys.size(); auto skeys = anim_track["scale"]; if (skeys.isNull()) { throw std::runtime_error("track " + bone_name + " in animation " + a.name + " has no scale keys"); } t.skey_count = skeys.size(); all_tracks.emplace_back(t); } for (auto tt = tracks.begin(); tt != tracks.end(); ++tt) { auto bone_name = tt.key().asString(); auto& anim_track = *tt; auto tkeys = anim_track["location"]; for (auto& tkey : tkeys) { auto frame = tkey["frame"]; if (frame.isNull()) { throw std::runtime_error("track " + bone_name + " in animations " + a.name + " has no frame number in keyframe"); } auto data = tkey["data"]; if (data.isNull()) { throw std::runtime_error("track " + bone_name + " in animation " + a.name + " has no data in keframe " + frame.asString()); } if (data.size() != 3) { throw std::runtime_error("data in keyframe " + frame.asString() + " in track " + bone_name + " in animation " + a.name + " is too small"); } translation_keyframe tk; tk.time = frame.asFloat(); tk.translate = glm::vec3{data[0].asFloat(), data[2].asFloat(), -data[1].asFloat()}; all_tkeys.emplace_back(tk); } auto qkeys = anim_track["rotation_quaternion"]; for (auto& qkey : qkeys) { auto frame = qkey["frame"]; if (frame.isNull()) { throw std::runtime_error("track " + bone_name + " in animations " + a.name + " has no frame number in keyframe"); } auto data = qkey["data"]; if (data.isNull()) { throw std::runtime_error("track " + bone_name + " in animation " + a.name + " has no data in keframe " + frame.asString()); } if (data.size() != 4) { throw std::runtime_error("data in keyframe " + frame.asString() + " in track " + bone_name + " in animation " + a.name + " is too small"); } rotation_keyframe rk; rk.time = frame.asFloat(); rk.rotate = glm::quat{data[0].asFloat(), data[1].asFloat(), data[2].asFloat(), data[3].asFloat()}; static auto offset = glm::angleAxis(glm::radians(-90.f), glm::vec3{1.f, 0.f, 0.f}); static auto offset_matrix = glm::toMat4(offset); static auto offset_matrix_t = glm::transpose(offset_matrix); auto rotation_matrix = glm::toMat4(rk.rotate); rotation_matrix = offset_matrix * rotation_matrix * offset_matrix_t; rk.rotate = glm::quat_cast(rotation_matrix); all_qkeys.emplace_back(rk); } auto skeys = anim_track["scale"]; for (auto& skey : skeys) { auto frame = skey["frame"]; if (frame.isNull()) { throw std::runtime_error("track " + bone_name + " in animations " + a.name + " has no frame number in keyframe"); } auto data = skey["data"]; if (data.isNull()) { throw std::runtime_error("track " + bone_name + " in animation " + a.name + " has no data in keframe " + frame.asString()); } if (data.size() != 3) { throw std::runtime_error("data in keyframe " + frame.asString() + " in track " + bone_name + " in animation " + a.name + " is too small"); } scale_keyframe sk; sk.time = frame.asFloat(); sk.scale = glm::vec3{data[0].asFloat(), data[2].asFloat(), -data[1].asFloat()}; all_skeys.emplace_back(sk); } } } auto animation_size = 20 + sizeof(float) + sizeof(int64_t); auto bone_count = int(h.bone_count); h.size = sizeof(header) + bone_count * sizeof(bone) + bone_count * sizeof(node) + (bone_count - 1) * sizeof(int32_t) + h.animation_count * animation_size + all_tracks.size() * sizeof(track) + all_tkeys.size() * sizeof(translation_keyframe) + all_qkeys.size() * sizeof(rotation_keyframe) + all_skeys.size() * sizeof(scale_keyframe); output.write(reinterpret_cast<char*>(&h), sizeof(header)); output.write(reinterpret_cast<char*>(bones.data()), bones.size() * sizeof(bone)); auto stuff = 0ul; for (auto i = 0ul; i < value["bone_hierachy"].size(); ++i) { node n; n.id = i; auto children = value["bone_hierachy"][std::to_string(i)]; n.children_count = children.size(); output.write(reinterpret_cast<char*>(&n), sizeof(node)); stuff += sizeof(node); for (auto& child : children) { output.write(reinterpret_cast<char*>(&child), sizeof(int32_t)); stuff += sizeof(int32_t); } } auto track_ptr = 0ul; auto tkey_ptr = 0ul; auto qkey_ptr = 0ul; auto skey_ptr = 0ul; for (auto& a : anims) { if (a.name.size() < 20) { output.write(a.name.c_str(), a.name.size() * sizeof(char)); for (auto i = 0ul; i < 20 - a.name.size(); ++i) { output.write("\0", sizeof(char)); } } else { output.write(a.name.c_str(), 20 * sizeof(char)); } output.write(reinterpret_cast<char*>(&a.length), sizeof(float)); output.write(reinterpret_cast<char*>(&a.track_count), sizeof(size_t)); for (auto i = uint64_t{0}; i < a.track_count; ++i) { auto& t = all_tracks[track_ptr + i]; output.write(reinterpret_cast<char*>(&t), sizeof(track)); for (auto i = 0ul; i < t.tkey_count; ++i) { output.write(reinterpret_cast<char*>(&all_tkeys[tkey_ptr + i]), sizeof(translation_keyframe)); } tkey_ptr += t.tkey_count; for (auto j = 0ul; j < t.qkey_count; ++j) { if (j > 0) { auto& q1 = all_qkeys[qkey_ptr + j - 1].rotate; auto& q2 = all_qkeys[qkey_ptr + j].rotate; auto scalar = glm::dot(q1, q2); if (scalar < 0.f) { q2 = -q2; } } output.write(reinterpret_cast<char*>(&all_qkeys[qkey_ptr + j]), sizeof(rotation_keyframe)); } qkey_ptr += t.qkey_count; for (auto k = 0ul; k < t.skey_count; ++k) { output.write(reinterpret_cast<char*>(&all_skeys[skey_ptr + k]), sizeof(scale_keyframe)); } skey_ptr += t.skey_count; } track_ptr += a.track_count; } } }
ValueKey Value::key() const { switch (opcode()) { case FramePointer: return ValueKey(opcode(), type()); case Identity: case Abs: case Ceil: case Sqrt: case SExt8: case SExt16: case SExt32: case ZExt32: case Clz: case Trunc: case IToD: case FloatToDouble: case DoubleToFloat: case Check: case BitwiseCast: case Neg: return ValueKey(opcode(), type(), child(0)); case Add: case Sub: case Mul: case Div: case Mod: case ChillDiv: case ChillMod: case BitAnd: case BitOr: case BitXor: case Shl: case SShr: case ZShr: case Equal: case NotEqual: case LessThan: case GreaterThan: case Above: case Below: case AboveEqual: case BelowEqual: case EqualOrUnordered: case CheckAdd: case CheckSub: case CheckMul: return ValueKey(opcode(), type(), child(0), child(1)); case Select: return ValueKey(opcode(), type(), child(0), child(1), child(2)); case Const32: return ValueKey(Const32, type(), static_cast<int64_t>(asInt32())); case Const64: return ValueKey(Const64, type(), asInt64()); case ConstDouble: return ValueKey(ConstDouble, type(), asDouble()); case ConstFloat: return ValueKey(ConstFloat, type(), asFloat()); case ArgumentReg: return ValueKey( ArgumentReg, type(), static_cast<int64_t>(as<ArgumentRegValue>()->argumentReg().index())); default: return ValueKey(); } }
//--------------------------------------------------------- bool CSG_Grid::_Save_Binary(CSG_File &Stream, int xA, int yA, int xN, int yN, TSG_Data_Type File_Type, bool bFlip, bool bSwapBytes) { char *Line, *pValue; int x, y, i, ix, iy, dy, axBytes, nxBytes, nValueBytes; //----------------------------------------------------- if( Stream.is_Open() && m_System.is_Valid() && m_Type != SG_DATATYPE_Undefined ) { Set_File_Type(GRID_FILE_FORMAT_Binary); if( bFlip ) { y = yA + yN - 1; dy = -1; } else { y = yA; dy = 1; } //------------------------------------------------- if( File_Type == SG_DATATYPE_Bit ) { nxBytes = xN / 8 + 1; if( m_Type == File_Type && m_Memory_Type == GRID_MEMORY_Normal && xA % 8 == 0 ) { axBytes = xA / 8; for(iy=0; iy<yN && SG_UI_Process_Set_Progress(iy, yN); iy++, y+=dy) { Stream.Write((char *)m_Values[y] + axBytes, sizeof(char), nxBytes); } } else { Line = (char *)SG_Malloc(nxBytes); for(iy=0; iy<yN && SG_UI_Process_Set_Progress(iy, yN); iy++, y+=dy) { for(ix=0, x=xA, pValue=Line; ix<xN; pValue++) { for(i=0; i<8 && ix<xN; i++, ix++, x++) { *pValue = asChar(x, y) != 0.0 ? *pValue | m_Bitmask[i] : *pValue & (~m_Bitmask[i]); } } Stream.Write(Line, sizeof(char), nxBytes); } SG_Free(Line); } } //------------------------------------------------- else { nValueBytes = SG_Data_Type_Get_Size(File_Type); nxBytes = xN * nValueBytes; if( m_Type == File_Type && m_Memory_Type == GRID_MEMORY_Normal && !bSwapBytes ) { axBytes = xA * nValueBytes; for(iy=0; iy<yN && SG_UI_Process_Set_Progress(iy, yN); iy++, y+=dy) { Stream.Write((char *)m_Values[y] + axBytes, sizeof(char), nxBytes); } } else { Line = (char *)SG_Malloc(nxBytes); for(iy=0; iy<yN && SG_UI_Process_Set_Progress(iy, yN); iy++, y+=dy) { for(ix=0, x=xA, pValue=Line; ix<xN; ix++, x++, pValue+=nValueBytes) { switch( File_Type ) { default: break; case SG_DATATYPE_Byte: *(BYTE *)pValue = asChar (x, y); break; case SG_DATATYPE_Char: *(char *)pValue = asChar (x, y); break; case SG_DATATYPE_Word: *(WORD *)pValue = asShort (x, y); break; case SG_DATATYPE_Short: *(short *)pValue = asShort (x, y); break; case SG_DATATYPE_DWord: *(DWORD *)pValue = asInt (x, y); break; case SG_DATATYPE_Int: *(int *)pValue = asInt (x, y); break; case SG_DATATYPE_Float: *(float *)pValue = asFloat (x, y); break; case SG_DATATYPE_Double: *(double *)pValue = asDouble (x, y); break; } if( bSwapBytes ) { _Swap_Bytes(pValue, nValueBytes); } } Stream.Write(Line, sizeof(char), nxBytes); } SG_Free(Line); } } //------------------------------------------------- SG_UI_Process_Set_Ready(); return( true ); } return( false ); }
// compare values. looks strange in order to be compatible with Excel int KCValue::compare(const KCValue& v) const { KCValue::Type t1 = d->type; KCValue::Type t2 = v.type(); // errors always less than everything else if ((t1 == Error) && (t2 != Error)) return -1; if ((t2 == Error) && (t1 != Error)) return 1; // comparing errors only yields 0 if they are the same if ((t1 == Error) && (t2 == Error)) return errorMessage() != v.errorMessage(); // empty == empty if ((t1 == Empty) && (t2 == Empty)) return 0; // empty value is always less than string // (except when the string is empty) if ((t1 == Empty) && (t2 == String)) return(v.asString().isEmpty()) ? 0 : -1; // boolean vs boolean if ((t1 == Boolean) && (t2 == Boolean)) { bool p = asBoolean(); bool q = v.asBoolean(); if (p) return q ? 0 : 1; else return q ? -1 : 0; } // boolean is always greater than integer if ((t1 == Boolean) && (t2 == Integer)) return 1; // boolean is always greater than float if ((t1 == Boolean) && (t2 == Float)) return 1; // boolean is always greater than string if ((t1 == Boolean) && (t2 == String)) return 1; // integer is always less than boolean if ((t1 == Integer) && (t2 == Boolean)) return -1; // integer vs integer if ((t1 == Integer) && (t2 == Integer)) { qint64 p = asInteger(); qint64 q = v.asInteger(); return (p == q) ? 0 : (p < q) ? -1 : 1; } // integer vs float if ((t1 == Integer) && (t2 == Float)) return compare(asFloat(), v.asFloat()); // integer is always less than string if ((t1 == Integer) && (t2 == String)) return -1; // float is always less than boolean if ((t1 == Float) && (t2 == Boolean)) return -1; // float vs integer if ((t1 == Float) && (t2 == Integer)) return compare(asFloat(), v.asFloat()); // float vs float if ((t1 == Float) && (t2 == Float)) return compare(asFloat(), v.asFloat()); // float is always less than string if ((t1 == Float) && (t2 == String)) return -1; // TODO Stefan: Complex // string is always greater than empty value // (except when the string is empty) if ((t1 == String) && (t2 == Empty)) return(asString().isEmpty()) ? 0 : 1; // string is always less than boolean if ((t1 == String) && (t2 == Boolean)) return -1; // string is always greater than integer if ((t1 == String) && (t2 == Integer)) return 1; // string is always greater than float if ((t1 == String) && (t2 == Float)) return 1; // The-Real-String comparison if ((t1 == String) && (t2 == String)) return asString().compare(v.asString()); // Undefined, actually allowComparison would return false return 0; }
bool KCValue::isZero() const { if (!isNumber()) return false; return isZero(asFloat()); }
static jobject ValueVector2SFSArray(JNIEnv* env, const ValueVector& valueVector, jobject javaObj) { jclass cls = env->GetObjectClass(javaObj); if (!cls) return javaObj; for (auto it = valueVector.begin(); it != valueVector.end(); ++it) { if (it->getType() == Value::Type::BYTE) { jmethodID mid = env->GetMethodID(cls, "addByte", "(B)V"); if (mid) env->CallVoidMethod(javaObj, mid, it->asByte()); } else if (it->getType() == Value::Type::INTEGER) { jmethodID mid = env->GetMethodID(cls, "addInt", "(I)V"); if (mid) env->CallVoidMethod(javaObj, mid, it->asInt()); } else if (it->getType() == Value::Type::FLOAT) { jmethodID mid = env->GetMethodID(cls, "addFloat", "(F)V"); if (mid) env->CallVoidMethod(javaObj, mid, it->asFloat()); } else if (it->getType() == Value::Type::DOUBLE) { jmethodID mid = env->GetMethodID(cls, "addFloat", "(F)V"); if (mid) env->CallVoidMethod(javaObj, mid, it->asDouble()); } else if (it->getType() == Value::Type::BOOLEAN) { jmethodID mid = env->GetMethodID(cls, "addBool", "(Z)V"); if (mid) env->CallVoidMethod(javaObj, mid, it->asBool()); } else if (it->getType() == Value::Type::STRING) { jmethodID mid = env->GetMethodID(cls, "addUtfString", "(Ljava/lang/String;)V"); if (mid) { jobject javaValue = env->NewStringUTF(it->asString().c_str()); env->CallVoidMethod(javaObj, mid, javaValue); env->DeleteLocalRef(javaValue); } } else if (it->getType() == Value::Type::VECTOR) { jmethodID mid = env->GetMethodID(cls, "addSFSArray", "(Lcom/smartfoxserver/v2/entities/data/ISFSArray;)V"); if (mid) { jobject javaSFSArray = getSFSArray(env); jobject javaValue = ValueVector2SFSArray(env, it->asValueVector(), javaSFSArray); env->CallVoidMethod(javaObj, mid, javaValue); env->DeleteLocalRef(javaValue); } } else if (it->getType() == Value::Type::MAP) { jmethodID mid = env->GetMethodID(cls, "addSFSObject", "(Lcom/smartfoxserver/v2/entities/data/ISFSObject;)V"); if (mid) { jobject sub_obj = getSFSObject(env); jobject javaValue = ValueMap2SFSObject(env, it->asValueMap(), sub_obj); env->CallVoidMethod(javaObj, mid, javaValue); env->DeleteLocalRef(javaValue); } } else if (it->getType() == Value::Type::INT_KEY_MAP) { } } env->DeleteLocalRef(cls); return javaObj; }
Variant::operator float() const { return asFloat(); }
inline operator float() const { return asFloat(); }