[GUÍA] PEV->BODY (uso/funcionamiento/tips)
#1
Ladrillo 
Buenas tardes, en esta oportunidad les traigo la traducción (+info) de esta guía sobre cómo utilizar y sacarle mayor provecho al pev->body (EV_INT_body/pev_body).

Toda la información que provenga de mi parte será escrita usando como fuente en algunas partes "Trebuchet MS" y en otras "Comic Sans MS".

Comencemos.



pev->body

Es un valor que le indica al juego qué sub-modelo debería ser visible.
Esto puede ser en extremo poderoso, por ejemplo, con modelos de jugadores; excepto que nadie parece haber utilizado la función de este valor en todo su potencial. Hasta ahora, y hasta donde tengo entendido, CS solo usa esto para mostrar el modelo de la bomba (C4) en el jugador.

¿Qué se puede hacer con este valor?

Por ejemplo (siguiendo el caso de los modelos de jugadores), se podrían poner todos los modelos personalizados de jugadores adjunto con sombreros (hats) en un solo modelo y subirlo al servidor. Esto tiene muchas mas ventajas que contras (abajo detallare mejor).

¿Cómo se manejan las combinaciones?

Digamos que tienes un modelo con dos grupos de sub-modelos (EJ: modelos y sombreros):
ASI NO ES COMO FUNCIONA:
Código:
Modelo1 - ID: 0
Modeol2 - ID: 1
Modelo3 - ID: 2
Sombrero1 - ID: 3
Sombrero2 - ID: 4
Sombrero3 - ID: 5

ASI ES COMO FUNCIONA:
Código:
Modelo1 - ID: 0
Modeol2 - ID: 1
Modelo3 - ID: 2
Sombrero1 - ID: 0
Sombrero2 - ID: 1
Sombrero3 - ID: 2

+INFO
Cada grupo tiene un parámetro 'base' que le dice al engine desde donde inicia (para setearlo a pev->body)
Ahora, digamos que tienes un modelo con 3 grupos, ejemplo:
Código PHP:
grupo 1
{
     
sub_model 1
     sub_model 2
     sub_model 3
     sub_model 4
     sub_model 5
}

grupo 2
{
      
sub_model 1
     sub_model 2
     sub_model 3
}

grupo 3
{
     
sub_model 1
     sub_model 2
     sub_model 3
     sub_model 4
     sub_model 5
     sub_model 6
     sub_model 7


Estos serán 'apilados' (el engine los interpretara) de una manera como esta:
• la base del grupo-1 siempre es 1 (o mejor dicho, el primer grupo siempre toma como base '1')
• la base de todos los grupos sub-secuentes se calcula desde donde termina la base del grupo anterior

Ahora, hagamos un ejemplo manual, para ver paso a paso cómo es calculado el valor:
Código PHP:
grupo 1
{
     
base(primer grupo)
     
sub-models 5
     cada sub
-model de este grupo es calculado asi sub-model n 1
     
     sub
-model 1 0
     sub
-model 2 1
     sub
-model 3 2
     sub
-model 4 3
     sub
-model 5 4
}

grupo 2
{
     
basebase_del_grupo_anterior numero_de_sub_models_del_grupo_anterior
     base
(5 sub-models 1 de base)
     
     
sub-models3
     cada sub
-model de este grupo es calculado asisub-model n = (sub-model n 1) * (base_de_este_grupo)
     
     
sub-model 1 = (1) * 0
     sub
-model 2 = (1) * 5
     sub
-model 3 = (1) * 10
}

grupo 3
{
     
basebase_del_grupo_anterior numero_de_sub_models_del_grupo_anterior
     base
15 (3 sub-models anteriores 5 de base)
     
     
sub-models7
     cada sub
-model de este grupo es calculado asisub-model n = (sub-model n 1) * (base_de_este_grupo)
     
     
sub-model 1 = (1) * 15 15 0
     sub
-model 2 = (1) * 15 15 15
     sub
-model 3 = (1) * 15 15 30
     sub
-model 4 = (1) * 15 15 45
     sub
-model 5 = (1) * 15 15 60


Ahora, imaginen que queremos asignar los siguientes grupos (con sus partes):
- grupo-1 + sub-model-5
- grupo-2 + sub-model-2
- grupo-3 + sub-model-5

El valor que debería tener pev->body para mostrar cada uno de estos grupos(+partes) sería la suma de cada uno:
- grupo-1 sub-model 5 = 5 - 1 = 4
- grupo-2 sub-model 2 = (2 - 1) * 5 = 1 * 5 = 5
- grupo-3 sub-model 5 = (5 - 1) * 15 = 4 * 15 = 60

Es decir: 4 + 5 + 60 = 69 (este valor, mostrara cada grupo con su respectiva parte).

Por supuesto (se estarán pensando), para poder calcular estos valores uno tiene que poder visualizar los grupos del modelo con algún editor (ejemplo HLMV), para poder calcular qué base tendrá cada grupo y el número de sub-models, y así calcular el valor completo.

Pero, ¿para qué se puede usar exactamente?

Bueno, por ejemplo, se puede hacer un plugin para personalizar por completo un personaje (al estilo RPG). Creando un modelo con grupos como: cara, cabello, pecho, espalda, botas, anillos, entre otros y unirlos en uno solo, y de esa manera el jugador puede elegir qué traje usar.

Ventajas
- Al estar todos los modelos en un solo archivo, puede dar una mejor "sensación" al descargar desde el juego.

- Funciona como una muy buena manera de reducir el numero de archivos precacheados en el juego (lo que nos aleja de llegar al temible "Precache Limit")

- El tamaño del modelo (ya compilado) termina siendo mas pequeño que la suma del tamaño de los modelos unidos, principalmente debido a que la información duplicada (como las animaciones, las secuencias, entre otros) son removidas.

- En el caso específico de los hats no se necesitaría de un plugin para manejarlos (lo que evita crear una entidad, setear el origin, etc); con solo cambiar el pev->body es suficiente.

- Abre un abanico nuevo de posibilidades para los modders.

Desventajas

- Si se quieren añadir más modelos, se requerirá descargar por completo el archivo (lo que implica que los jugadores, deberían eliminar el modelo viejo y descargar el nuevo); o en su defecto, asignarle un nuevo nombre al modelo y así se descargara como uno nuevo.

- Puede resultar un poco difícil de entender a la primera.

- Existe un numero máximo de combinaciones posibles (se exceptúa DoD el cual tiene un manejo especial de este valor), el cual es de 255.

- En cuanto al compilador, el modelo final no puede tener un peso superior a los 16MB (por lo que si al combinar los modelos en uno solo, este termina pesando más, se deberá partir por dividirlo en 2+ modelos separados).

- No conviene asignar muchos grupos a un modelo (y mucho más si cada grupo tiene muchos sub-models), dado que los últimos grupos terminan teniendo bases tan grandes que sus combinaciones sobrepasan el máximo (255).



Eso es todo, dudas/sugerencias, estoy al pendiente.
Saludos
Responder
#2
EXTRA

He creado este stock (un port de SetBodyGroup del Half-Life) para hacer la tarea más facil:
Código PHP:
stock bool:SetBodyGroup(const iEntity, const iGroup, const iPart)
{
    new 
bool:bResult;
    
    static 
szModel[64];
    
pev(iEntitypev_modelszModelcharsmax(szModel));
    
    new 
iModelPtr fopen(szModel"rb");
    if (!
iModelPtr)
        goto 
Result;
    
    new 
iBodyPartsCount iGroup;
    new 
iBodyPartNumModels;
    new 
iBodyPartBase;
    
Model_GetBodyPartInfo(iModelPtriBodyPartsCountiBodyPartNumModelsiBodyPartBase);
    
    if (
iGroup iBodyPartsCount)
        goto 
Result;
    
    if (
iPart >= iBodyPartNumModels)
        goto 
Result;
    
    new 
iBody;
    new 
iCurrent;
    
    
iBody pev(iEntitypev_body);
    
iCurrent = (iBody iBodyPartBase) % iBodyPartNumModels;
    
iBody iBody - (iCurrent iBodyPartBase) + (iPart iBodyPartBase);
    
    
set_pev(iEntitypev_bodyiBody);
    
bResult true
    
    Result
:
    {
        
fclose(iModelPtr);
        return 
bResult;
    }
}

Model_GetBodyPartInfo(const pmodel, &numbodyparts, &nummodels, &base)
{
    if (!
pmodel)
        return;
    
    new 
group numbodyparts;
    new 
bodypartindex;
    
    const 
studiohdr_s_numbodyparts 204 // studiohdr_t->numbodyparts offset (from start)
    
const mstudiobodyparts_s_nummodels 64// mstudiobodyparts_t->nummodels offset (from start)
    
const mstudiobodyparts_s_size 76// mstudiobodyparts_t size (64char x 1byte + 3int * 4byte)

    
fseek(pmodelstudiohdr_s_numbodypartsSEEK_SET);
    
fread(pmodelnumbodypartsBLOCK_INT);
    
fread(pmodelbodypartindexBLOCK_INT);
    
    
bodypartindex += (group mstudiobodyparts_s_size) + mstudiobodyparts_s_nummodels;
    
    
fseek(pmodelbodypartindexSEEK_SET);
    
fread(pmodelnummodelsBLOCK_INT);
    
fread(pmodelbaseBLOCK_INT);


SetBodygroup (HLSDK)
Código:
void SetBodygroup( void *pmodel, entvars_t *pev, int iGroup, int iValue )
{
    studiohdr_t *pstudiohdr;
    
    pstudiohdr = (studiohdr_t *)pmodel;
    if (! pstudiohdr)
        return;

    if (iGroup > pstudiohdr->numbodyparts)
        return;

    mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + iGroup;

    if (iValue >= pbodypart->nummodels)
        return;

    int iCurrent = (pev->body / pbodypart->base) % pbodypart->nummodels;

    pev->body = (pev->body - (iCurrent * pbodypart->base) + (iValue * pbodypart->base));
}

Al igual, que he dejado adjunto un modelo de prueba, para que puedan hacer sus pruebas

Se puede usar tan solo como esto:
Código PHP:
SetBodyGroup(entitybody-groupbody-part

Usando el mismo modelo, por ejemplo:
Código PHP:
SetBodyGroup(entity01);
SetBodyGroup(entity24); 

Resultado:
[Imagen: Qq4wEm6.jpg]


Archivos adjuntos
.rar   svc.rar (Tamaño: 1.68 MB / Descargas: 8)
2
Responder
#3
(19/05/2023, 02:47 PM)SVC escribió: Buenas tardes, en esta oportunidad les traigo la traducción (+info) de esta guía sobre cómo utilizar y sacarle mayor provecho al pev->body (EV_INT_body/pev_body).

Toda la información que provenga de mi parte será escrita usando como fuente en algunas partes "Trebuchet MS" y en otras "Comic Sans MS".

Comencemos.



pev->body

Es un valor que le indica al juego qué sub-modelo debería ser visible.
Esto puede ser en extremo poderoso, por ejemplo, con modelos de jugadores; excepto que nadie parece haber utilizado la función de este valor en todo su potencial. Hasta ahora, y hasta donde tengo entendido, CS solo usa esto para mostrar el modelo de la bomba (C4) en el jugador.

¿Qué se puede hacer con este valor?

Por ejemplo (siguiendo el caso de los modelos de jugadores), se podrían poner todos los modelos personalizados de jugadores adjunto con sombreros (hats) en un solo modelo y subirlo al servidor. Esto tiene muchas mas ventajas que contras (abajo detallare mejor).

¿Cómo se manejan las combinaciones?

Digamos que tienes un modelo con dos grupos de sub-modelos (EJ: modelos y sombreros):
ASI NO ES COMO FUNCIONA:
Código:
Modelo1 - ID: 0
Modeol2 - ID: 1
Modelo3 - ID: 2
Sombrero1 - ID: 3
Sombrero2 - ID: 4
Sombrero3 - ID: 5

ASI ES COMO FUNCIONA:
Código:
Modelo1 - ID: 0
Modeol2 - ID: 1
Modelo3 - ID: 2
Sombrero1 - ID: 0
Sombrero2 - ID: 1
Sombrero3 - ID: 2

+INFO
Cada grupo tiene un parámetro 'base' que le dice al engine desde donde inicia (para setearlo a pev->body)
Ahora, digamos que tienes un modelo con 3 grupos, ejemplo:
Código PHP:
grupo 1
{
     
sub_model 1
     sub_model 2
     sub_model 3
     sub_model 4
     sub_model 5
}

grupo 2
{
      
sub_model 1
     sub_model 2
     sub_model 3
}

grupo 3
{
     
sub_model 1
     sub_model 2
     sub_model 3
     sub_model 4
     sub_model 5
     sub_model 6
     sub_model 7


Estos serán 'apilados' (el engine los interpretara) de una manera como esta:
• la base del grupo-1 siempre es 1 (o mejor dicho, el primer grupo siempre toma como base '1')
• la base de todos los grupos sub-secuentes se calcula desde donde termina la base del grupo anterior

Ahora, hagamos un ejemplo manual, para ver paso a paso cómo es calculado el valor:
Código PHP:
grupo 1
{
     
base(primer grupo)
     
sub-models 5
     cada sub
-model de este grupo es calculado asi sub-model n 1
     
     sub
-model 1 0
     sub
-model 2 1
     sub
-model 3 2
     sub
-model 4 3
     sub
-model 5 4
}

grupo 2
{
     
basebase_del_grupo_anterior numero_de_sub_models_del_grupo_anterior
     base
(5 sub-models 1 de base)
     
     
sub-models3
     cada sub
-model de este grupo es calculado asisub-model n = (sub-model n 1) * (base_de_este_grupo)
     
     
sub-model 1 = (1) * 0
     sub
-model 2 = (1) * 5
     sub
-model 3 = (1) * 10
}

grupo 3
{
     
basebase_del_grupo_anterior numero_de_sub_models_del_grupo_anterior
     base
15 (3 sub-models anteriores 5 de base)
     
     
sub-models7
     cada sub
-model de este grupo es calculado asisub-model n = (sub-model n 1) * (base_de_este_grupo)
     
     
sub-model 1 = (1) * 15 15 0
     sub
-model 2 = (1) * 15 15 15
     sub
-model 3 = (1) * 15 15 30
     sub
-model 4 = (1) * 15 15 45
     sub
-model 5 = (1) * 15 15 60


Ahora, imaginen que queremos asignar los siguientes grupos (con sus partes):
- grupo-1 + sub-model-5
- grupo-2 + sub-model-2
- grupo-3 + sub-model-5

El valor que debería tener pev->body para mostrar cada uno de estos grupos(+partes) sería la suma de cada uno:
- grupo-1 sub-model 5 = 5 - 1 = 4
- grupo-2 sub-model 2 = (2 - 1) * 5 = 1 * 5 = 5
- grupo-3 sub-model 5 = (5 - 1) * 15 = 4 * 15 = 60

Es decir: 4 + 5 + 60 = 69 (este valor, mostrara cada grupo con su respectiva parte).

Por supuesto (se estarán pensando), para poder calcular estos valores uno tiene que poder visualizar los grupos del modelo con algún editor (ejemplo HLMV), para poder calcular qué base tendrá cada grupo y el número de sub-models, y así calcular el valor completo.

Pero, ¿para qué se puede usar exactamente?

Bueno, por ejemplo, se puede hacer un plugin para personalizar por completo un personaje (al estilo RPG). Creando un modelo con grupos como: cara, cabello, pecho, espalda, botas, anillos, entre otros y unirlos en uno solo, y de esa manera el jugador puede elegir qué traje usar.

Ventajas
- Al estar todos los modelos en un solo archivo, puede dar una mejor "sensación" al descargar desde el juego.

- Funciona como una muy buena manera de reducir el numero de archivos precacheados en el juego (lo que nos aleja de llegar al temible "Precache Limit")

- El tamaño del modelo (ya compilado) termina siendo mas pequeño que la suma del tamaño de los modelos unidos, principalmente debido a que la información duplicada (como las animaciones, las secuencias, entre otros) son removidas.

- En el caso específico de los hats no se necesitaría de un plugin para manejarlos (lo que evita crear una entidad, setear el origin, etc); con solo cambiar el pev->body es suficiente.

- Abre un abanico nuevo de posibilidades para los modders.

Desventajas

- Si se quieren añadir más modelos, se requerirá descargar por completo el archivo (lo que implica que los jugadores, deberían eliminar el modelo viejo y descargar el nuevo); o en su defecto, asignarle un nuevo nombre al modelo y así se descargara como uno nuevo.

- Puede resultar un poco difícil de entender a la primera.

- Existe un numero máximo de combinaciones posibles (se exceptúa DoD el cual tiene un manejo especial de este valor), el cual es de 255.

- En cuanto al compilador, el modelo final no puede tener un peso superior a los 16MB (por lo que si al combinar los modelos en uno solo, este termina pesando más, se deberá partir por dividirlo en 2+ modelos separados).

- No conviene asignar muchos grupos a un modelo (y mucho más si cada grupo tiene muchos sub-models), dado que los últimos grupos terminan teniendo bases tan grandes que sus combinaciones sobrepasan el máximo (255).



Eso es todo, dudas/sugerencias, estoy al pendiente.
Saludos

Me costó como 1 hora entenderlo pero tiene mucha lógica. Propongo que lo expliques aún mejor para la gente retrasada como yo lo entienda mejor. Roflmao Roflmao Roflmao
Responder
#4
Me alegra que te haya servido.
Cualquier duda, estoy al pendiente.

Qué exactamente no entendías y/o se te dificulto?
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)