void TrackMD3Angles(entity_t *e, LPCSTR key, LPCSTR value)
{
  if (strcmpi(key, "angle") != 0)
  {
    return;
  }

#ifdef SOF
  if (e->eclass->fixedsize && 
		(
			(strnicmp(e->eclass->name, "misc_",			5) == 0) ||
			(strnicmp(e->eclass->name, "light_",		6) == 0) || 
			(strnicmp(e->eclass->name, "m_",			2) == 0) ||
			(strnicmp(e->eclass->name, "item_weapon_",	12)== 0) ||
			(strnicmp(e->eclass->name, "item_ammo_",	10)== 0)
		)
	  )
#else
  if (e->eclass->fixedsize && strnicmp (e->eclass->name, "misc_model",10) == 0)
#endif
  {
    float a = FloatForKey (e, "angle");
    float b = atof(value);
    if (a != b)
    {
      vec3_t vAngle;
      vAngle[0] = vAngle[1] = 0;
      vAngle[2] = -a;
      Brush_Rotate(e->brushes.onext, vAngle, e->origin, true);
      vAngle[2] = b;
      Brush_Rotate(e->brushes.onext, vAngle, e->origin, true);

#ifdef QUAKE3
	  //
	  // auto assign new bounding box to model?
	  //
	  char *_p = ValueForKey(e, "mins");
	  char *_p2= ValueForKey(e, "maxs");
	  char *_p3= ValueForKey(e, sKEYFIELD_AUTOBOUND);
	  //
	  // if either key is missing then update both... (or if they do exist, but were only set by this code in the first place and therefore can be overwritten)
	  //
	  if ( ((strlen(_p) == 0) || (strlen(_p2) == 0)) || strlen(_p3) )
	  {
		SetKeyValue (e, sKEYFIELD_AUTOBOUND, "1");

		vec3_t vMins,vMaxs;

		VectorSubtract(e->brushes.onext->mins, e->origin, vMins);
		VectorSubtract(e->brushes.onext->maxs, e->origin, vMaxs);

		SetKeyValue (e, "mins", va("%i %i %i", (int)vMins[0], (int)vMins[1], (int)vMins[2]));
		SetKeyValue (e, "maxs", va("%i %i %i", (int)vMaxs[0], (int)vMaxs[1], (int)vMaxs[2]));
	  }
#endif


    }
  }
}
// Scale object bounding box
void TrackMD3Scale(entity_t *e, LPCSTR key, LPCSTR value)
{
	float oldscale,scale;

	if (strcmpi(key, "scale") != 0)
	{
		return;
	}

	if (e->eclass->fixedsize && ((strnicmp(e->eclass->name, "misc_",5) == 0) ||
			(strnicmp(e->eclass->name, "light_",6) == 0)))
	{
		oldscale = FloatForKey (e, "scale");
		scale = atof(value);
		if (oldscale != scale)	// Value unchanged??????
		{
	      Brush_Scale2(e->eclass,e->brushes.onext, scale,e->origin,true);

			float a = FloatForKey (e, "angle");
			if (a)
			{
				// Re-rotate bbox
				vec3_t vAngle;
				vAngle[0] = vAngle[1] = 0;
				vAngle[2] = a;
				Brush_Rotate(e->brushes.onext, vAngle, e->origin, true);
			}
		} 
	}
}
Exemple #3
0
/*
 =======================================================================================================================
 =======================================================================================================================
 */
void TrackMD3Angles(entity_t *e, const char *key, const char *value) {
	if ( idStr::Icmp(key, "angle") != 0 ) {
		return;
	}

	if ((e->eclass->fixedsize && e->eclass->nShowFlags & ECLASS_MISCMODEL) || EntityHasModel(e)) {
		float	a = FloatForKey(e, "angle");
		float	b = atof(value);
		if (a != b) {
			idVec3	vAngle;
			vAngle[0] = vAngle[1] = 0;
			vAngle[2] = -a;
			Brush_Rotate(e->brushes.onext, vAngle, e->origin, true);
			vAngle[2] = b;
			Brush_Rotate(e->brushes.onext, vAngle, e->origin, true);
		}
	}
}
void CPlugInManager::CommitEntityHandleToMap(LPVOID vpEntity)
{
	entity_t *pe;
	eclass_t *e;
	brush_t		*b;
	vec3_t mins,maxs;
	bool has_brushes;
	for (int i=0 ; i < m_EntityHandles.GetSize() ; i++ )
	{
		if (vpEntity == m_EntityHandles.GetAt(i))
		{
			m_EntityHandles.RemoveAt(i);
			pe = reinterpret_cast<entity_t*>(vpEntity);
			// fill additional fields
			// straight copy from Entity_Parse
			// entity_t::origin
			GetVectorForKey (pe, "origin", pe->origin);
			// entity_t::eclass
			if (pe->brushes.onext == &pe->brushes)
				has_brushes = false;
			else
				has_brushes = true;
			e = Eclass_ForName (ValueForKey (pe, "classname"), has_brushes);
			pe->eclass = e;
			// fixedsize
			if (e->fixedsize)
			{
				if (pe->brushes.onext != &pe->brushes)
				{
					Sys_Printf("Warning : Fixed size entity with brushes in CPlugInManager::CommitEntityHandleToMap\n");
				}
				// create a custom brush
				VectorAdd(e->mins, pe->origin, mins);
				VectorAdd(e->maxs, pe->origin, maxs);
				float a = 0;
				if (e->nShowFlags & ECLASS_MISCMODEL)
				{
					char* p = ValueForKey(pe, "model");
					if (p != NULL && strlen(p) > 0)
					{
						vec3_t vMin, vMax;
						a = FloatForKey (pe, "angle");
				        if (GetCachedModel(pe, p, vMin, vMax))
				        {
						      // create a custom brush
						      VectorAdd (pe->md3Class->mins, pe->origin, mins);
						      VectorAdd (pe->md3Class->maxs, pe->origin, maxs);
				        }
					}
			    }
		
			    b = Brush_Create (mins, maxs, &e->texdef);

			    if (a)
			    {
					vec3_t vAngle;
					vAngle[0] = vAngle[1] = 0;
					vAngle[2] = a;
					Brush_Rotate(b, vAngle, pe->origin, false);
				}

				b->owner = pe;

				b->onext = pe->brushes.onext;
				b->oprev = &pe->brushes;
				pe->brushes.onext->oprev = b;
				pe->brushes.onext = b;
			}
			else
			{	// brush entity
				if (pe->brushes.next == &pe->brushes)
					Sys_Printf ("Warning: Brush entity with no brushes in CPlugInManager::CommitEntityHandleToMap\n");
			}

			// add brushes to the active brushes list
			// and build them along the way
			for (b=pe->brushes.onext ; b != &pe->brushes ; b=b->onext)
			{
				// convert between old brushes and brush primitive
				if (g_qeglobals.m_bBrushPrimitMode)
				{
					// we only filled the shift scale rot fields, needs conversion
					Brush_Build( b, true, true, true );
				}
				else
				{
					// we are using old brushes
					Brush_Build( b );
				}
				b->next = active_brushes.next;
				active_brushes.next->prev = b;
				b->prev = &active_brushes;
				active_brushes.next = b;
			}

			// handle worldspawn entities
			// if worldspawn has no brushes, use the new one
			if (!strcmp(ValueForKey (pe, "classname"), "worldspawn"))
			{
				if ( world_entity && ( world_entity->brushes.onext != &world_entity->brushes ) )
				{
					// worldspawn already has brushes
					Sys_Printf ("Commiting worldspawn as func_group\n");
					SetKeyValue(pe, "classname", "func_group");
					// add the entity to the end of the entity list
					pe->next = &entities;
					pe->prev = entities.prev;
					entities.prev->next = pe;
					entities.prev = pe;
					g_qeglobals.d_num_entities++;
				}
				else
				{
					// there's a worldspawn with no brushes, we assume the map is empty
					if ( world_entity )
					{
						Entity_Free( world_entity );
						world_entity = pe;
					}
					else
						Sys_Printf("Warning : unexpected world_entity == NULL in CommitEntityHandleToMap\n");
				}
			}
			else
			{
				// add the entity to the end of the entity list
				pe->next = &entities;
				pe->prev = entities.prev;
				entities.prev->next = pe;
				entities.prev = pe;
				g_qeglobals.d_num_entities++;
			}
		}
	}
}
entity_t *Entity_PostParse(entity_t *ent, brush_t *pList)
{
    bool		has_brushes;
    eclass_t	*e;
    brush_t		*b;
    idVec3		mins, maxs, zero;
    idBounds bo;

    zero.Zero();

    Entity_SetCurveData( ent );

    if (ent->brushes.onext == &ent->brushes)
    {
        has_brushes = false;
    }
    else
    {
        has_brushes = true;
    }

    bool needsOrigin = !GetVectorForKey(ent, "origin", ent->origin);
    const char	*pModel = ValueForKey(ent, "model");

    const char *cp = ValueForKey(ent, "classname");

    if (strlen(cp))
    {
        e = Eclass_ForName(cp, has_brushes);
    }
    else
    {
        const char *cp2 = ValueForKey(ent, "name");
        if (strlen(cp2))
        {
            char buff[1024];
            strcpy(buff, cp2);
            int len = strlen(buff);
            while ((isdigit(buff[len-1]) || buff[len-1] == '_') && len > 0)
            {
                buff[len-1] = '\0';
                len--;
            }
            e = Eclass_ForName(buff, has_brushes);
            SetKeyValue(ent, "classname", buff, false);
        }
        else
        {
            e = Eclass_ForName("", has_brushes);
        }
    }

    idStr str;

    if (e->defArgs.GetString("model", "", str) && e->entityModel == NULL)
    {
        e->entityModel = gameEdit->ANIM_GetModelFromEntityDef( &e->defArgs );
    }

    ent->eclass = e;

    bool hasModel = EntityHasModel(ent);

    if (hasModel)
    {
        ent->eclass->defArgs.GetString("model", "", str);
        if (str.Length())
        {
            hasModel = false;
            ent->epairs.Delete("model");
        }
    }

    if (e->nShowFlags & ECLASS_WORLDSPAWN)
    {
        ent->origin.Zero();
        needsOrigin = false;
        ent->epairs.Delete( "model" );
    }
    else if (e->nShowFlags & ECLASS_LIGHT)
    {
        if (GetVectorForKey(ent, "light_origin", ent->lightOrigin))
        {
            GetMatrixForKey(ent, "light_rotation", ent->lightRotation);
            ent->trackLightOrigin = true;
        }
        else if (hasModel)
        {
            SetKeyValue(ent, "light_origin", ValueForKey(ent, "origin"));
            ent->lightOrigin = ent->origin;
            if (GetMatrixForKey(ent, "rotation", ent->lightRotation))
            {
                SetKeyValue(ent, "light_rotation", ValueForKey(ent, "rotation"));
            }
            ent->trackLightOrigin = true;
        }
    }
    else if ( e->nShowFlags & ECLASS_ENV )
    {
        // need to create an origin from the bones here
        idVec3 org;
        idAngles ang;
        bo.Clear();
        bool hasBody = false;
        const idKeyValue *arg = ent->epairs.MatchPrefix( "body ", NULL );
        while ( arg )
        {
            sscanf( arg->GetValue(), "%f %f %f %f %f %f", &org.x, &org.y, &org.z, &ang.pitch, &ang.yaw, &ang.roll );
            bo.AddPoint( org );
            arg = ent->epairs.MatchPrefix( "body ", arg );
            hasBody = true;
        }
        if (hasBody)
        {
            ent->origin = bo.GetCenter();
        }
    }

    if (e->fixedsize || hasModel)  			// fixed size entity
    {
        if (ent->brushes.onext != &ent->brushes)
        {
            for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext)
            {
                b->entityModel = true;
            }
        }

        if (hasModel)
        {
            // model entity
            idRenderModel *modelHandle = renderModelManager->FindModel( pModel );

            if ( dynamic_cast<idRenderModelPrt*>( modelHandle ) || dynamic_cast<idRenderModelLiquid*>( modelHandle ) )
            {
                bo.Zero();
                bo.ExpandSelf( 12.0f );
            }
            else
            {
                bo = modelHandle->Bounds( NULL );
            }

            VectorCopy(bo[0], mins);
            VectorCopy(bo[1], maxs);
            for (int i = 0; i < 3; i++)
            {
                if (mins[i] == maxs[i])
                {
                    mins[i]--;
                    maxs[i]++;
                }
            }
            VectorAdd(mins, ent->origin, mins);
            VectorAdd(maxs, ent->origin, maxs);
            b = Brush_Create(mins, maxs, &e->texdef);
            b->modelHandle = modelHandle;

            float		yaw = 0;
            bool		convertAngles = GetFloatForKey(ent, "angle", &yaw);
            extern void Brush_Rotate(brush_t *b, idMat3 matrix, idVec3 origin, bool bBuild);
            extern void Brush_Rotate(brush_t *b, idVec3 rot, idVec3 origin, bool bBuild);

            if (convertAngles)
            {
                idVec3	rot(0, 0, yaw);
                Brush_Rotate(b, rot, ent->origin, false);
            }

            if (GetMatrixForKey(ent, "rotation", ent->rotation))
            {
                idBounds bo2;
                bo2.FromTransformedBounds(bo, ent->origin, ent->rotation);
                b->owner = ent;
                Brush_Resize(b, bo2[0], bo2[1]);
            }
            Entity_LinkBrush(ent, b);
        }

        if (!hasModel || (ent->eclass->nShowFlags & ECLASS_LIGHT && hasModel))
        {
            // create a custom brush
            if (ent->trackLightOrigin)
            {
                mins = e->mins + ent->lightOrigin;
                maxs = e->maxs + ent->lightOrigin;
            }
            else
            {
                mins = e->mins + ent->origin;
                maxs = e->maxs + ent->origin;
            }

            b = Brush_Create(mins, maxs, &e->texdef);
            GetMatrixForKey(ent, "rotation", ent->rotation);
            Entity_LinkBrush(ent, b);
            b->trackLightOrigin = ent->trackLightOrigin;
            if ( e->texdef.name == NULL )
            {
                brushprimit_texdef_t bp;
                texdef_t td;
                td.SetName( ent->eclass->defMaterial );
                Brush_SetTexture( b, &td, &bp, false );
            }
        }
    }
    else  	// brush entity
    {
        if (ent->brushes.next == &ent->brushes)
        {
            printf("Warning: Brush entity with no brushes\n");
        }

        if (!needsOrigin)
        {
            idStr cn = ValueForKey(ent, "classname");
            idStr name = ValueForKey(ent, "name");
            idStr model = ValueForKey(ent, "model");
            if (cn.Icmp("func_static") == 0)
            {
                if (name.Icmp(model) == 0)
                {
                    needsOrigin = true;
                }
            }
        }

        if (needsOrigin)
        {
            idVec3	mins, maxs, mid;
            int		i;
            char	text[32];
            mins[0] = mins[1] = mins[2] = 999999;
            maxs[0] = maxs[1] = maxs[2] = -999999;

            // add in the origin
            for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext)
            {
                Brush_Build(b, true, false, false);
                for (i = 0; i < 3; i++)
                {
                    if (b->mins[i] < mins[i])
                    {
                        mins[i] = b->mins[i];
                    }

                    if (b->maxs[i] > maxs[i])
                    {
                        maxs[i] = b->maxs[i];
                    }
                }
            }

            for (i = 0; i < 3; i++)
            {
                ent->origin[i] = (mins[i] + ((maxs[i] - mins[i]) / 2));
            }

            sprintf(text, "%i %i %i", (int)ent->origin[0], (int)ent->origin[1], (int)ent->origin[2]);
            SetKeyValue(ent, "origin", text);
        }

        if (!(e->nShowFlags & ECLASS_WORLDSPAWN))
        {
            if (e->defArgs.FindKey("model") == NULL && (pModel == NULL || (pModel && strlen(pModel) == 0)))
            {
                SetKeyValue(ent, "model", ValueForKey(ent, "name"));
            }
        }
        else
        {
            DeleteKey(ent, "origin");
        }
    }

    // add all the brushes to the main list
    if (pList)
    {
        for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext)
        {
            b->next = pList->next;
            pList->next->prev = b;
            b->prev = pList;
            pList->next = b;
        }
    }

    FixFloats(&ent->epairs);

    return ent;

}