CString CHotKey::GetHotKeyDisplayStatic(DWORD dwHotKey)
{
	CString keyDisplay;
	UINT modifiers = GetModifier(HIBYTE(dwHotKey));
	if(modifiers & MOD_SHIFT)
	{
		keyDisplay += _T("Shift + ");
	}

	if(modifiers & MOD_CONTROL)
	{
		keyDisplay += _T("Ctrl + ");
	}

	if(modifiers & MOD_ALT)
	{
		keyDisplay += _T("Alt + ");
	}

	if(modifiers & MOD_WIN)
	{
		keyDisplay += _T("Win + ");
	}

	keyDisplay += GetVirKeyName(LOBYTE(dwHotKey));

	return keyDisplay;
}
示例#2
0
STATIC TOKEN_T lexDollar( void )
/*******************************
 * pre:     $ read off input
 * post:    0 or more characters of token read
 * returns: MAC token type
 */
{
    STRM_T  s;
    TOKEN_T t;

    s = PreGetCH();

    if( (Glob.compat_nmake || Glob.compat_posix) && ismsspecial( s ) ) {
        t = LexMSDollar( s );
        GetModifier();
        return( t );
    }
    switch( s ) {
    case DOLLAR:                        return( MAC_DOLLAR );
    case COMMENT:                       return( MAC_COMMENT );
    case '(':                           return( MAC_OPEN );
    case '+':                           return( MAC_EXPAND_ON );
    case '-':                           return( MAC_EXPAND_OFF );
    case '^':                           return( lexFormQualifier( MAC_CUR ) );
    case '[':                           return( lexFormQualifier( MAC_FIRST ) );
    case ']':                           return( lexFormQualifier( MAC_LAST ) );
    case '@': CurAttr.u.form = FORM_FULL;  return( MAC_CUR );       /* UNIX */
    case '*': CurAttr.u.form = FORM_NOEXT; return( MAC_CUR );       /* UNIX */
    case '<': CurAttr.u.form = FORM_FULL;  return( MAC_ALL_DEP );   /* UNIX */
    case '?': CurAttr.u.form = FORM_FULL;  return( MAC_YOUNG_DEP ); /* UNIX */
    default:
        UnGetCH( s );
        return( MAC_START );
    }
}
示例#3
0
文件: xcb.c 项目: FLYKingdom/vlc
static void Mapping( intf_thread_t *p_intf )
{
    static const xcb_keysym_t p_x11_modifier_ignored[] = {
        0,
        XK_Num_Lock,
        XK_Scroll_Lock,
        XK_Caps_Lock,
    };

    intf_sys_t *p_sys = p_intf->p_sys;

    p_sys->i_map = 0;
    p_sys->p_map = NULL;

    /* Registering of Hotkeys */
    for( struct hotkey *p_hotkey = p_intf->p_libvlc->p_hotkeys;
            p_hotkey->psz_action != NULL;
            p_hotkey++ )
    {
        char *psz_hotkey;
        if( asprintf( &psz_hotkey, "global-%s", p_hotkey->psz_action ) < 0 )
            break;

        const int i_vlc_action = p_hotkey->i_action;
        const int i_vlc_key = config_GetInt( p_intf, psz_hotkey );

        free( psz_hotkey );

        if( !i_vlc_key )
            continue;

        const xcb_keycode_t key = xcb_key_symbols_get_keycode( p_sys->p_symbols, GetX11Key( i_vlc_key & ~KEY_MODIFIER ) );
        const unsigned i_modifier = GetX11Modifier( p_sys->p_connection, p_sys->p_symbols, i_vlc_key & KEY_MODIFIER );

        for( int j = 0; j < sizeof(p_x11_modifier_ignored)/sizeof(*p_x11_modifier_ignored); j++ )
        {
            const unsigned i_ignored = GetModifier( p_sys->p_connection, p_sys->p_symbols, p_x11_modifier_ignored[j] );
            if( j != 0 && i_ignored == 0x00)
                continue;

            hotkey_mapping_t *p_map_old = p_sys->p_map;
            p_sys->p_map = realloc( p_sys->p_map, sizeof(*p_sys->p_map) * (p_sys->i_map+1) );
            if( !p_sys->p_map )
            {
                p_sys->p_map = p_map_old;
                break;
            }
            hotkey_mapping_t *p_map = &p_sys->p_map[p_sys->i_map++];

            p_map->i_x11 = key;
            p_map->i_modifier = i_modifier|i_ignored;
            p_map->i_action = i_vlc_action;
        }
    }
}
示例#4
0
文件: xcb.c 项目: 371816210/vlc_vlc
static unsigned GetX11Modifier( xcb_connection_t *p_connection,
        xcb_key_symbols_t *p_symbols, unsigned i_vlc )
{
    unsigned i_mask = 0;

    if( i_vlc & KEY_MODIFIER_ALT )
        i_mask |= GetModifier( p_connection, p_symbols, XK_Alt_L ) |
                  GetModifier( p_connection, p_symbols, XK_Alt_R );
    if( i_vlc & KEY_MODIFIER_SHIFT )
        i_mask |= GetModifier( p_connection, p_symbols, XK_Shift_L ) |
                  GetModifier( p_connection, p_symbols, XK_Shift_R );
    if( i_vlc & KEY_MODIFIER_CTRL )
        i_mask |= GetModifier( p_connection, p_symbols, XK_Control_L ) |
                  GetModifier( p_connection, p_symbols, XK_Control_R );
    if( i_vlc & KEY_MODIFIER_META )
        i_mask |= GetModifier( p_connection, p_symbols, XK_Meta_L ) |
                  GetModifier( p_connection, p_symbols, XK_Meta_R ) |
                  GetModifier( p_connection, p_symbols, XK_Super_L ) |
                  GetModifier( p_connection, p_symbols, XK_Super_R );
    return i_mask;
}
示例#5
0
	void TermTab::handleUrlActivated (const QUrl& url)
	{
		const auto modifiers = QApplication::keyboardModifiers ();

		const auto& selectedStr = XmlSettingsManager::Instance ()
				.property ("LinkActivationModifier").toString ();
		const auto selected = GetModifier (selectedStr);

		if (selected != Qt::NoModifier && !(modifiers & selected))
			return;

		const auto& entity = Util::MakeEntity (url, {}, TaskParameter::FromUserInitiated);
		CoreProxy_->GetEntityManager ()->HandleEntity (entity);
	}
BOOL CHotKey::ValidateHotKey(DWORD dwHotKey)
{
	ATOM id = ::GlobalAddAtom(_T("HK_VALIDATE"));
	BOOL bResult = ::RegisterHotKey( g_HotKeys.m_hWnd,
		id,
		GetModifier(HIBYTE(dwHotKey)),
		LOBYTE(dwHotKey) );

	if(bResult)
		::UnregisterHotKey(g_HotKeys.m_hWnd, id);

	::GlobalDeleteAtom(id);

	return bResult;
}
示例#7
0
float LootRandomizer::GetModifierPercentProbability(int modifierID, int modifierType)
{
    LootModifier* modifier = GetModifier(modifierID);

    if(!modifier)
        return 0;

    if(modifierType == psGMSpawnMods::ITEM_PREFIX)
        return modifier->probabilityRange/prefix_max;
    // 1=suffix
    else if(modifierType == psGMSpawnMods::ITEM_SUFFIX)
        return modifier->probabilityRange/suffix_max;
    // 2=adjective
    else if(modifierType == psGMSpawnMods::ITEM_ADJECTIVE)
        return modifier->probabilityRange/adjective_max;
    else
        Error2("Unknown modifierID: %d",modifierID);

    return 0;
}
bool CHotKey::Register()
{
	if(m_Key)
	{
		if(m_bIsRegistered == false)
		{
			ASSERT(g_HotKeys.m_hWnd);
			m_bIsRegistered = ::RegisterHotKey(g_HotKeys.m_hWnd,
				m_Atom,
				GetModifier(),
				LOBYTE(m_Key) ) == TRUE;
		}
	}
	else
	{
		m_bIsRegistered = false;
	}

	return m_bIsRegistered;
}
Modifier* SkeletalExporterBase::findModifier(INode* node, const Class_ID& classID)
{
    auto object = node->GetObjectRef();

    while (object && object->SuperClassID() == GEN_DERIVOB_CLASS_ID)
    {
        auto derivedObject = static_cast<IDerivedObject*>(object);

        // Iterate over all entries of the modifier stack.
        for (auto i = 0; i < derivedObject->NumModifiers(); i++)
        {
            // If this modifier is a physique then return it
            auto modifier = derivedObject->GetModifier(i);
            if (modifier->ClassID() == classID)
                return modifier;
        }

        object = derivedObject->GetObjRef();
    }

    return nullptr;
}
/*This damages the entiies health and will include damage reduction from defense modifiers**/
void ALivingEntity::InflictDamage(FLivingEntityDamage damage)
{
	if (currentHealth > 0){
		Modifier* modifier = GetModifier(ModifierManager::defenseModiferName);
		FString damagedBy = "Other";

		if (damage.damager != NULL) {
			damagedBy = damage.damager->entityName;
		}

		if (modifier) {
			damage.damageDone *= modifier->value;
		}

		FString damageDone = FString::SanitizeFloat(damage.damageDone);
		if ((currentHealth - damage.damageDone) > 0)
		{
			if (OnLivingEntityDamageEvent.IsBound())	{
				OnLivingEntityDamageEvent.Broadcast(damage);
			}

			GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, damagedBy + " delt " + damageDone + " damage to " + entityName);
			currentHealth -= damage.damageDone;
		}
		else
		{
			currentHealth -= damage.damageDone;

			if (OnLivingEntityDeathEvent.IsBound()){
				OnLivingEntityDeathEvent.Broadcast(this);
			}

			GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, entityName + " was killed!!!");
			//GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, FString::SanitizeFloat(currentHealth - Damage) +  " overkill damage!!");
			Destroy();
		}

	}
}
示例#11
0
psItem* LootRandomizer::SetModifiers(psItem* item, csArray<uint32_t>& mods)
{
    if (mods.GetSize() == 0)
        return item;

    bool found = false;
    uint32_t itemID = item->GetBaseStats()->GetUID();

    for(size_t i = 0; i < mods.GetSize(); i++)
    {
        LootModifier* lootModifier = GetModifier(mods[i]);

        if(!lootModifier || mods[i] == 0)
            continue;

        if(!lootModifier->IsAllowed(itemID))
        {
            continue;
        }

        printf("found\n");
        item->AddLootModifier(lootModifier->id, lootModifier->mod_id);
        found = true;
    }

    if (found)
    {
        // Regenerate the modifiers cache of the item
        item->UpdateModifiers();

        // At least one modifier as been added, so we make the item "identifiable"
        item->SetIsIdentifiable(true);
    }

    return item;
}
示例#12
0
/*
====================
ExportSelected
====================
*/
void G3DSExport::ExportSelected( INode* i_node )
{
	if(i_node->Selected() && i_node->Renderable())
	{
		Modifier *modifier = GetModifier(i_node,SKIN_CLASSID);
		if(modifier)
		{
			// disables the modifier in the viewports 
			modifier->DisableMod();

			// gather the skin data
			GatherSkin(i_node);

			// enables the modifier in the history browser 
			modifier->EnableMod();
		}
	}

	// process the child node
	for(int i = 0; i < i_node->NumberOfChildren(); i++)
	{
		ExportSelected(i_node->GetChildNode(i));
	}
}
示例#13
0
文件: xcb.c 项目: 371816210/vlc_vlc
static bool Mapping( intf_thread_t *p_intf )
{
    static const xcb_keysym_t p_x11_modifier_ignored[] = {
        0,
        XK_Num_Lock,
        XK_Scroll_Lock,
        XK_Caps_Lock,
    };

    intf_sys_t *p_sys = p_intf->p_sys;
    bool active = false;

    p_sys->i_map = 0;
    p_sys->p_map = NULL;

    /* Registering of Hotkeys */
    for( const struct hotkey *p_hotkey = p_intf->p_libvlc->p_hotkeys;
            p_hotkey->psz_action != NULL;
            p_hotkey++ )
    {
        char varname[12 + strlen( p_hotkey->psz_action )];
        sprintf( varname, "global-key-%s", p_hotkey->psz_action );

        char *key = var_InheritString( p_intf, varname );
        if( key == NULL )
            continue;

        uint_fast32_t i_vlc_key = vlc_str2keycode( key );
        free( key );
        if( i_vlc_key == KEY_UNSET )
            continue;

        xcb_keycode_t *p_keys = xcb_key_symbols_get_keycode(
                p_sys->p_symbols, GetX11Key( i_vlc_key & ~KEY_MODIFIER ) );
        if( !p_keys )
            continue;

        const unsigned i_modifier = GetX11Modifier( p_sys->p_connection,
                p_sys->p_symbols, i_vlc_key & KEY_MODIFIER );

        const size_t max = sizeof(p_x11_modifier_ignored) /
                sizeof(*p_x11_modifier_ignored);
        for( unsigned int i = 0; i < max; i++ )
        {
            const unsigned i_ignored = GetModifier( p_sys->p_connection,
                    p_sys->p_symbols, p_x11_modifier_ignored[i] );
            if( i != 0 && i_ignored == 0)
                continue;

            hotkey_mapping_t *p_map_old = p_sys->p_map;
            p_sys->p_map = realloc( p_sys->p_map,
                    sizeof(*p_sys->p_map) * (p_sys->i_map+1) );
            if( !p_sys->p_map )
            {
                p_sys->p_map = p_map_old;
                break;
            }
            hotkey_mapping_t *p_map = &p_sys->p_map[p_sys->i_map++];

            p_map->p_keys = p_keys;
            p_map->i_modifier = i_modifier|i_ignored;
            p_map->i_vlc = i_vlc_key;
            active = true;
        }
    }
    return active;
}
示例#14
0
void LootRandomizer::ApplyModifier(psItemStats* baseItem, RandomizedOverlay* overlay, csArray<uint32_t> &modifierIds)
{
    LootModifier mod;

    //set up default mod data
    mod.cost_modifier = 1;
    mod.name = baseItem->GetName();
    csArray<ValueModifier> variableValues;

    //creates the full lootmodifier from the ids being applied.
    //0 should be left empty in the database as it acts as NO HIT.
    for(size_t i = 0; i < modifierIds.GetSize(); i++)
    {
        uint32_t modID = modifierIds.Get(i);
        if(modID) //0 means nothing to do, no need to search for the void.
        {
            LootModifier* partialModifier = GetModifier(modID);
            if(partialModifier)
            {
                overlay->active = true;
                AddModifier(&mod, partialModifier);
            }
        }
    }
    //all is done no modifiers where found. so we just get out
    if(overlay->active == false)
        return;

    overlay->name = mod.name;
    overlay->price = psMoney(baseItem->GetPrice().GetTrias() * mod.cost_modifier);
    if(mod.mesh.Length() > 0)
        overlay->mesh = mod.mesh;
    if(mod.icon.Length() > 0)
        overlay->icon = mod.icon;

    // Apply effect
    csString xmlItemMod;

    xmlItemMod.Append("<ModiferEffects>");
    xmlItemMod.Append(mod.effect);
    xmlItemMod.Append("</ModiferEffects>");

    // Read the ModiferEffects XML into a doc*/
    csRef<iDocument> xmlDoc = ParseString(xmlItemMod);
    if(!xmlDoc)
    {
        Error1("Parse error in Loot Randomizer");
        return;
    }
    csRef<iDocumentNode> root    = xmlDoc->GetRoot();
    if(!root)
    {
        Error1("No XML root in Loot Randomizer");
        return;
    }
    csRef<iDocumentNode> topNode = root->GetNode("ModiferEffects");//Are we sure it is "Modifer"?
    if(!topNode)
    {
        Error1("No <ModiferEffects> in Loot Randomizer");
        return;
    }

    csRef<iDocumentNodeIterator> nodeList = topNode->GetNodes("ModiferEffect");

    // For Each ModiferEffect
    csRef<iDocumentNode> node;
    while(nodeList->HasNext())
    {
        node = nodeList->Next();
        //Determine the Effect
        csString EffectOp = node->GetAttribute("operation")->GetValue();
        csString EffectName = node->GetAttribute("name")->GetValue();
        float EffectValue = node->GetAttribute("value")->GetValueAsFloat();

        //Add to the Attributes
        if(!SetAttribute(EffectOp, EffectName, EffectValue, overlay, baseItem, variableValues))
        {
            // display error and continue
            Error2("Unable to set attribute %s on new loot item.",EffectName.GetData());
        }
    }

    // Apply stat_req_modifier
    csString xmlStatReq;

    xmlStatReq.Append("<StatReqs>");
    xmlStatReq.Append(mod.stat_req_modifier);
    xmlStatReq.Append("</StatReqs>");

    // Read the Stat_Req XML into a doc
    xmlDoc = ParseString(xmlStatReq);
    if(!xmlDoc)
    {
        Error1("Parse error in Loot Randomizer");
        return;
    }
    root    = xmlDoc->GetRoot();
    if(!root)
    {
        Error1("No XML root in Loot Randomizer");
        return;
    }
    topNode = root->GetNode("StatReqs");
    if(!topNode)
    {
        Error1("No <statreqs> in Loot Randomizer");
        return;
    }

    nodeList = topNode->GetNodes("StatReq");
    // For Each Stat_Req
    while(nodeList->HasNext())
    {
        node = nodeList->Next();
        //Determine the STAT
        ItemRequirement req;
        req.name = node->GetAttribute("name")->GetValue();
        req.min_value = node->GetAttribute("value")->GetValueAsFloat();
        //Add to the Requirements
        overlay->reqs.Push(req);
    }

    // Apply equip script
    if(!mod.equip_script.IsEmpty())
    {
        csString scriptXML = GenerateScriptXML(mod.name, mod.equip_script, variableValues);
        overlay->equip_script = ApplicativeScript::Create(psserver->entitymanager, psserver->GetCacheManager(), scriptXML);
    }

    //clamp speed at 1.5s to keep consistency with item_stats
    if(!CS::IsNaN(overlay->latency) && overlay->latency < 1.5F)
        overlay->latency = 1.5F;
}
bool ZealNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
    enabled = true;
#ifdef WIN32
    MSG* msg = static_cast<MSG*>(message);

    if(WM_HOTKEY == msg->message && msg->wParam == 10) {
        emit gotHotKey();
        return true;
    }
#elsif LINUX // WIN32 or LINUX
    xcb_generic_event_t* ev = static_cast<xcb_generic_event_t*>(message);
    if(((ev->response_type&127) == XCB_KEY_PRESS || (ev->response_type&127) == XCB_KEY_RELEASE) && !hotKey.isEmpty()) {
        // XCB_KEY_RELEASE must be ignored by Qt because otherwise it causes SIGSEGV in QXcbKeyboard::handleKeyReleaseEvent
        xcb_connection_t  *c = static_cast<xcb_connection_t*>(
              ((QGuiApplication*)QGuiApplication::instance())->
                    platformNativeInterface()->nativeResourceForWindow("connection", 0));
        xcb_key_press_event_t *event = (xcb_key_press_event_t *)ev;

        xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(c);
        xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, GetX11Key(hotKey[0]));

        bool found = false;
        // found=true means either (a) complete hotkey was pressed, or (b) any of its separate
        // keys was released. We return true in both cases, because key releases while window
        // is not present cause SIGSEGV in QXcbKeyboard::handleKeyReleaseEvent
        if((ev->response_type&127) == XCB_KEY_RELEASE) {
            QList<QPair<int, Qt::Modifier> > modifiers;
            modifiers.append(qMakePair(XK_Alt_L, Qt::ALT));
            modifiers.append(qMakePair(XK_Alt_R, Qt::ALT));
            modifiers.append(qMakePair(XK_Control_L, Qt::CTRL));
            modifiers.append(qMakePair(XK_Control_R, Qt::CTRL));
            modifiers.append(qMakePair(XK_Meta_L, Qt::META));
            modifiers.append(qMakePair(XK_Meta_R, Qt::META));
            for(auto modifier : modifiers) {
                if(!(hotKey[0] & modifier.second)) {
                    continue;
                }
                xcb_keycode_t *mod_keycodes = xcb_key_symbols_get_keycode(keysyms, modifier.first);
                if(mod_keycodes == nullptr) continue;
                int i = 0;
                while(mod_keycodes[i] != XCB_NO_SYMBOL) {
                    if(event->detail == mod_keycodes[i]) {
                        found = true;
                    }
                    i += 1;
                }
                free(mod_keycodes);
            }
        }
        int i = 0;
        while(keycodes[i] != XCB_NO_SYMBOL) {
            if(event->detail == keycodes[i]) {
                bool modifiers_present = true;
                if(hotKey[0] & Qt::ALT) {
                    if(!(event->state & GetModifier(c, keysyms, XK_Alt_L) || event->state & GetModifier(c, keysyms,  XK_Alt_R))) {
                        modifiers_present = false;
                    }
                }
                if(hotKey[0] & Qt::CTRL) {
                    if(!(event->state & GetModifier(c, keysyms, XK_Control_L) || event->state & GetModifier(c, keysyms,  XK_Control_R))) {
                        modifiers_present = false;
                    }
                }
                if(hotKey[0] & Qt::META) {
                    if(!(event->state & GetModifier(c, keysyms, XK_Meta_L) || event->state & GetModifier(c, keysyms,  XK_Meta_R))) {
                        modifiers_present = false;
                    }
                }
                if(hotKey[0] & Qt::SHIFT) {
                    if(!(event->state & GetModifier(c, keysyms, XK_Shift_L) || event->state & GetModifier(c, keysyms,  XK_Shift_R))) {
                        modifiers_present = false;
                    }
                }
                if(enabled && modifiers_present) {
                    xcb_allow_events(c, XCB_ALLOW_ASYNC_KEYBOARD, event->time);
                    if((ev->response_type&127) == XCB_KEY_PRESS) {
                        emit gotHotKey();
                    }
                    found = true;
                } else {
                    if((ev->response_type&127) == XCB_KEY_RELEASE) {
                        found = true;
                    }
                    xcb_allow_events(c, XCB_ALLOW_REPLAY_KEYBOARD, event->time);
                }
                break;
            }
            i += 1;
        }
        free(keysyms);
        free(keycodes);
        if(found) return true;
    }
#endif // WIN32 or LINUX
    return false;
}
示例#16
0
/*
====================
GatherSkin
====================
*/
void G3DSExport::GatherSkin(INode* i_node)
{
	SKIN skin;

	// get the name of the node
	skin.name = i_node->GetName();

	// get the skin interface
	Modifier *modifier = GetModifier(i_node,SKIN_CLASSID);
	ISkin* i_skin = (ISkin*)modifier->GetInterface(I_SKIN);
	MAX_CHECK(i_skin);

	// convert to the triangle type
	Mesh* i_mesh = NULL;
	Object* obj = i_node->EvalWorldState(mTime).obj;
	if(obj && ( obj->SuperClassID() == GEOMOBJECT_CLASS_ID ))
	{
		if(obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) 
		{ 
			TriObject *tri_obj = (TriObject*)obj->ConvertToType(mTime, Class_ID(TRIOBJ_CLASS_ID, 0)); MAX_CHECK(tri_obj);
			i_mesh = &tri_obj->mesh;
		}
	}
	MAX_CHECK(i_mesh&&i_mesh->getNumFaces()&&i_mesh->getNumVerts());

	// get the material
	skin.texture = "textures/default.tga";
	Mtl* mtl = i_node->GetMtl();
	if(mtl && (mtl->ClassID()==Class_ID(DMTL_CLASS_ID, 0)) && ((StdMat*)mtl)->MapEnabled(ID_DI)) 
	{
		Texmap *texmap = mtl->GetSubTexmap(ID_DI);
		if(texmap && texmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0x00))
		{
			skin.texture = UnifySlashes(((BitmapTex *)texmap)->GetMapName());
			if( !strstr( skin.texture.c_str(), mPath.c_str() ) )
			{
				G3DAssert("The material(%s) is error : the texture path(%s) is illegal!",mtl->GetName(), skin.texture.c_str());
			}
			else
			{
				skin.texture = strstr(skin.texture.c_str(),mPath.c_str()) + strlen(mPath.c_str());
			}
		}
	}

	// if it has uvs
	int map_count = i_mesh->getNumMaps();
	bool has_uvs = i_mesh->getNumTVerts() && i_mesh->tvFace;
	if(!(has_uvs&&map_count)) { G3DAssert("The skin(%s) has not the uv coordinates.",skin.name.c_str()); return; }

	// get the transform
	Matrix3 mesh_matrix = i_node->GetObjectTM(mTime);
	Matrix3 node_matrix = i_node->GetNodeTM(mTime);
	Matrix3 transform = mesh_matrix * Inverse(node_matrix);

	// get the points
	skin.points.assign(i_mesh->verts, i_mesh->verts+i_mesh->getNumVerts());

	// get the triangles
	for(int i = 0; i < i_mesh->getNumFaces(); i++)
	{
		Face& face = i_mesh->faces[i];

		TRIANGLE tri;		
		tri.smoothing = face.smGroup;
		for(int j = 0; j < 3; j++)
		{
			VPTNIS v;
			v.pos = transform * i_mesh->verts[face.v[j]];

			// get the uv
			UVVert * map_verts = i_mesh->mapVerts(1);
			TVFace * map_faces = i_mesh->mapFaces(1);
			v.uv = reinterpret_cast<Point2&>(map_verts[map_faces[i].t[j]]);
			v.uv.y = 1 - v.uv.y;

			// initialize the normal
			v.normal = Point3::Origin;

			// get the vertex index
			v.index = face.v[j];

			// get the smoothing group
			v.smoothing = face.smGroup;			

			// set the index for the triangle
			tri.index0[j] = v.index;

			// reassemble the vertex list
			tri.index1[j] = AddVertex(skin, v);
		}

		// add the triangle to the table
		skin.triangles.push_back(tri);
	}

	// build the index map
	for( int i = 0; i < skin.vertexes.size(); i++ )
	{
		skin.vertex_index_map[skin.vertexes[i].index].push_back(i);
	}

	// get the skin context data
	ISkinContextData* i_skin_context_data = i_skin->GetContextInterface(i_node);
	if(i_skin_context_data == NULL) { G3DAssert("The skin(%s) has not the weight.",skin.name.c_str()); return; }

	// gets the initial matrix of the skinned object 
	Matrix3 initial_object_transform;
	i_skin->GetSkinInitTM(i_node, initial_object_transform, true);

	// process the points
	int num_points = i_skin_context_data->GetNumPoints();
	for(int i = 0; i < num_points; i++)
	{
		MAX_CHECK(i < skin.points.size());

		VPIW viw;

		// get the initial point				
		viw.pos = initial_object_transform * skin.points[i];

		// process the weights		
		std::multimap< float, int > weights;

		// get the number of bones that control this vertex
		int num_bones = i_skin_context_data->GetNumAssignedBones(i);
		if(num_bones>0)
		{
			for (int j = 0; j < num_bones; j++)
			{
				Matrix3 transform;

				// get the assigned bone of the point 
				INode* i_bone_node = i_skin->GetBone(i_skin_context_data->GetAssignedBone(i, j));
				MAX_CHECK(i_bone_node != NULL);

				// get the weight of the bone
				float weight = i_skin_context_data->GetBoneWeight(i, j);

				// add the weight to the table
				weights.insert(std::make_pair(weight, AddBone(skin,i_bone_node)));
			}
		}
		else
		{
			// add the weight to the table
			weights.insert(std::make_pair(1.f, AddBone(skin,i_node)));
		}

		// recalculate the weights
		float weight0 = 0.f, weight1 = 0.f, weight2 = 0.f;
		int index0 = 0, index1 = 0, index2 = 0;
		std::multimap< float, int >::iterator it = weights.end();
		it--;
		weight0 = it->first;
		index0 = it->second;
		if(it != weights.begin())
		{
			it--;
			weight1 = it->first;
			index1 = it->second;
			if(it != weights.begin())
			{
				it--;
				weight2 = it->first;
				index2 = it->second;
			}
		}		
		float sum_weights = weight0 + weight1 + weight2;

		// store the skin weights	
		viw.weight[0]	= weight0/sum_weights;
		viw.index[0]	= index0;
		viw.weight[1]	= weight1/sum_weights;
		viw.index[1]	= index1;
		viw.weight[2]	= weight2/sum_weights;
		viw.index[2]	= index2;
		skin.weights.push_back(viw);
	}

	// get the initial transforms
	skin.transforms.resize(skin.bones.size());
	for(int i = 0; i < skin.bones.size(); i++)
	{
		INode* node = skin.bones[i];
		Matrix3 mat;
		if (SKIN_INVALID_NODE_PTR == i_skin->GetBoneInitTM( node, mat ))
		{
			if (SKIN_INVALID_NODE_PTR == i_skin->GetSkinInitTM( node, mat ))
			{
				mat.IdentityMatrix();
			}
		}
		skin.transforms[i] = Inverse(mat);
	}

	// there is a 75 bone limit for each skinned object.
	if(skin.bones.size()>75)
	{
		G3DAssert("There are more %d bones in the skin(%s).",skin.bones.size(), i_node->GetName());
		return;
	}

	// reset the skin vertex position
	for(int i = 0; i < skin.vertexes.size(); i++)
	{
		VPTNIS& v0 = skin.vertexes[i];
		VPIW& v1 = skin.weights[v0.index];
		v0.pos = v1.pos;
	}

	// build the normal space
	BuildNormal(skin);

	// calculate the bounding box	
	skin.box.Init();
	for(int i = 0; i < skin.vertexes.size(); i++)
	{
		Point3 pt = node_matrix * skin.vertexes[i].pos;
		skin.box += pt;
	}

	// add the skin to the table
	mSkins.push_back(skin);
}