Esempio n. 1
0
void RuntimeSpriteObject::ChangeScale( const gd::String & operatorStr, double newScale)
{
    //TODO : Generate appropriate code calling SetScaleX/Y instead of this.
    if ( operatorStr == "=" )
    {
        SetScaleX(newScale);
        SetScaleY(newScale);
    }
    else if ( operatorStr == "+" )
    {
        SetScaleX(GetScaleX()+newScale);
        SetScaleY(GetScaleY()+newScale);
    }
    else if ( operatorStr == "-" )
    {
        SetScaleX(GetScaleX()-newScale);
        SetScaleY(GetScaleY()-newScale);
    }
    else if ( operatorStr == "*" )
    {
        SetScaleX(GetScaleX()*newScale);
        SetScaleY(GetScaleY()*newScale);
    }
    else if ( operatorStr == "/" )
    {
        SetScaleX(GetScaleX()/newScale);
        SetScaleY(GetScaleY()/newScale);
    }

    return;
}
Esempio n. 2
0
void SpriteGroup::Render()
{
	Element::Render();

	for (int i = 0; i < m_sprite_list.size(); ++i)
	{
		Sprite* sprite = m_sprite_list.at(i);
		sprite->Render();

		sprite->SetPosition(
			sprite->GetPositionX() - GetPositionX(),
			sprite->GetPositionY() - GetPositionY(),
			sprite->GetPositionZ() - GetPositionZ());

		sprite->SetAngle(
			sprite->GetAngleX() - GetAngleX(),
			sprite->GetAngleY() - GetAngleY(),
			sprite->GetAngleZ() - GetAngleZ());

		sprite->SetAnchor(
			sprite->GetAnchorX() * 2.0f - GetAnchorX(),
			sprite->GetAnchorY() * 2.0f - GetAnchorY());

		if (GetScaleX() != 0)
		{
			sprite->SetScaleX(sprite->GetScaleX() / GetScaleX());
		}
		if (GetScaleY() != 0)
		{
			sprite->SetScaleY(sprite->GetScaleY() / GetScaleY());
		}
	}
}
Esempio n. 3
0
void wxSVGCtrlBase::RepaintBuffer() {
	int w = -1, h = -1;
	if (m_fitToFrame)
		GetClientSize(&w, &h);

	//wxDateTime time = wxDateTime::UNow();

	if (m_repaintRect.width > 0 && m_repaintRect.height > 0
			&& (m_repaintRect.width < 2 * m_buffer.GetWidth() / 3
					|| m_repaintRect.height < 2 * m_buffer.GetHeight() / 3)) {
		m_repaintRect.x = wxMax(m_repaintRect.x, 0);
		m_repaintRect.y = wxMax(m_repaintRect.y, 0);
		wxSVGRect rect(m_repaintRect.x / GetScaleX(), m_repaintRect.y / GetScaleY(),
				m_repaintRect.width / GetScaleX(), m_repaintRect.height / GetScaleY());
		wxBitmap bitmap = m_doc->Render(w, h, &rect);
		wxMemoryDC dc;
		dc.SelectObject(m_buffer);
		dc.DrawBitmap(bitmap, m_repaintRect.x, m_repaintRect.y);
	} else
		m_buffer = wxBitmap(m_doc->Render(w, h));

	m_repaintRect = wxRect();

	//wxLogError(wxDateTime::UNow().Subtract(time).Format(wxT("draw buffer %l ms")));
}
Esempio n. 4
0
void wxSVGCtrlBase::Refresh(const wxSVGRect* rect) {
	if (!rect || rect->IsEmpty())
		Refresh(true, NULL);
	else {
		wxRect winRect((int) (rect->GetX() * GetScaleX()), (int) (rect->GetY() * GetScaleY()),
				(int) (rect->GetWidth() * GetScaleX()), (int) (rect->GetHeight() * GetScaleY()));
		RefreshRect(winRect);
	}
}
Esempio n. 5
0
void CModel::UpdateMatrices()
{
	// Rotation
	D3DXMATRIX translation;
	D3DXMATRIX scale;
	D3DXMATRIX matrixRotationX;
	D3DXMATRIX matrixRotationY;
	D3DXMATRIX matrixRotationZ;

	// Calculate the rotation of the model.
	float rotX = (GetRotationX() * PrioEngine::kPi) / 180.0f;
	float rotY = (GetRotationY() * PrioEngine::kPi) / 180.0f;
	float rotZ = (GetRotationZ() * PrioEngine::kPi) / 180.0f;

	D3DXMatrixRotationX(&matrixRotationX, rotX);
	D3DXMatrixRotationY(&matrixRotationY, rotY);
	D3DXMatrixRotationZ(&matrixRotationZ, rotZ);

	// Calculate scaling.
	D3DXMatrixScaling(&scale, GetScaleX(), GetScaleY(), GetScaleZ());

	// Calculate the translation of the model.
	D3DXMatrixTranslation(&translation, GetPosX(), GetPosY(), GetPosZ());

	// Calculate the world matrix
	mWorldMatrix = scale * matrixRotationX * matrixRotationY * matrixRotationZ * translation;
}
Esempio n. 6
0
void Label::Render()
{
    cText.SetBlending(eBlendOperation);
    cText.SetColor(iColor.pixel);
    cText.SetScale(GetScaleX(), GetScaleY());
    cText.SetScale(fTextScaleX, fTextScaleY);
    cText.SetPosition(this->GetX(), this->GetY());
    cText.SetLocalPosition(this->GetLocalX(), this->GetLocalY());

    switch (iAlign)
    {
    case HorizontalAlignRight:
    {
        cText.SetPosition(this->GetX() + ((this->GetWidth() - cText.GetWidth())), this->GetY());
    }
    break;

    case HorizontalAlignCenter:
    {
        cText.SetPosition(this->GetX() + ((this->GetWidth() - cText.GetWidth()) / 2.0f), this->GetY());
    }
    break;

    case HorizontalAlignNone:
    case HorizontalAlignLeft:
    default:
        break;
    }

    cText.Draw();

    if (pConfiguration->bDebugText)
        pRendererDevice->DrawRect(this->GetX(), this->GetY(), this->GetWidth(), this->GetHeight(), PIXEL_COLOR(0, 255, 0, 255));
}
Esempio n. 7
0
//-----------------------------------------------------------------------------
void LineProfileCanvas::OnPaintCustom( wxPaintDC& dc )
//-----------------------------------------------------------------------------
{
    wxCoord yOffset( 1 ), w( 0 ), h( 0 );
    dc.GetSize( &w, &h );
    const double scaleX = static_cast<double>( w - 2 * GetBorderWidth() ) / static_cast<double>( ( GetDataCount() == 0 ) ? 1 : GetDataCount() - 1 );
    const double scaleY = GetScaleY( h );
    DrawMarkerLines( dc, w, h, scaleX );
    unsigned int from, to;
    GetDrawRange( &from, &to );
    const int borderWidth = GetBorderWidth();
    const wxString YMarkerString( wxString::Format( wxT( "Draw Range(absolute): %d / %d, " ), from, to ) );
    wxCoord xOffset;
    dc.GetTextExtent( YMarkerString, &xOffset, 0 );
    xOffset += borderWidth / 2;
    dc.DrawText( YMarkerString, borderWidth / 2, yOffset );
    if( m_boUnsupportedPixelFormat )
    {
        dc.SetTextForeground( *wxRED );
        dc.DrawText( wxString( wxT( "Unsupported pixel format" ) ), xOffset, yOffset );
        dc.SetTextForeground( *wxBLACK );
    }
    else if( m_ppData )
    {
        for( int channel = 0; channel < m_ChannelCount; channel++ )
        {
            DrawProfileLine( dc, h, borderWidth + 1, scaleX, scaleY, from, to, m_ppData[channel], GetDataCount(), *m_Pens[channel].pColour_ );
            DrawInfoString( dc, wxString::Format( wxT( "%s%s: " ), ( channel != 0 ) ? wxT( ", " ) : wxT( "" ), m_Pens[channel].description_.c_str() ), xOffset, yOffset, *( m_Pens[channel].pColour_ ) );
        }
    }
}
Esempio n. 8
0
bool FieldView::on_button_press_event(GdkEventButton* event){
    //we get aproximatly coordinats of cell
    //here we add 0.1463 to avoid some infelicity
    const double xm = (event->x) / CELL_SIZE / GetScaleX();
    const double ym = (event->y) / CELL_SIZE / GetScaleY();

    //we find fractional part of coordinats, then it will help us to round coordinats
    const double xdiff = xm - abs(xm);
    const double ydiff = ym - abs(ym);

    int xc, yc;

    //here we round our coordinats
    if(xdiff <= 0.25)
        xc = abs(xm) - 1;
    else if(xdiff >= 0.75)
        xc = abs(xm);
    else xc = -1;

    if(ydiff <= 0.25)
        yc = abs(ym) - 1;
    else if(ydiff >= 0.75)
        yc = abs(ym);
    else yc = -1;
    //when xc or yc are equal to -1 it means that signal mustn't be handled

    if((xc >= 0) && (yc >= 0))
        ctrl->MakeMove(Coordinates(xc, yc)); //emit signal
    return true;
}
Esempio n. 9
0
void SpriteGroup::Update(const float& delta)
{
	Element::Update(delta);

	for (int i = 0; i < m_sprite_list.size(); ++i)
	{
		Sprite* sprite = m_sprite_list.at(i);
		sprite->SetPosition(
			sprite->GetPositionX() + GetPositionX(),
			sprite->GetPositionY() + GetPositionY(),
			sprite->GetPositionZ() + GetPositionZ());

		sprite->SetAngle(
			sprite->GetAngleX() + GetAngleX(),
			sprite->GetAngleY() + GetAngleY(),
			sprite->GetAngleZ() + GetAngleZ());

		sprite->SetAnchor(
			(sprite->GetAnchorX() + GetAnchorX()) / 2.0f,
			(sprite->GetAnchorY() + GetAnchorY()) / 2.0f);

		sprite->SetScale(
			sprite->GetScaleX() * GetScaleX(),
			sprite->GetScaleY() * GetScaleY());

		sprite->Update(delta);
	}
}
Esempio n. 10
0
void RuntimeSpriteObject::SetScaleY(float val)
{
    if (val == GetScaleY()) return;
    if (val < 0) val = 0;

    scaleY = val * (isFlippedY ? -1.0 : 1.0);
    needUpdateCurrentSprite = true;
}
Esempio n. 11
0
	void Matrix::SetRotation ( float rotation )
	{   
		const float rot_x	= atan2f(  b, a );
		const float rot_y	= atan2f( -c, d );
		const float scale_x	= GetScaleX();
		const float scale_y	= GetScaleY();
		
		a = ( scale_x * cos( rotation ) );
		b = ( scale_x * sin( rotation ) );
		c = ( scale_y * sin( rot_y - rot_x + rotation ) * -1 );		// reverse sign.
		d = ( scale_y * cos( rot_y - rot_x + rotation ) );
	}
void IsometricSprite::UpdateCollisionBox()
{
	double x, y, w, h,cx,cy;
	x = GetX() - GetImage()->GetHandleX() *fabs(GetScaleX());
	y = GetY() - GetImage()->GetHandleX() *fabs(GetScaleY());
	w = GetImage()->GetWidth()*fabs(GetScaleX());
	h = GetImage()->GetWidth()*fabs(GetScaleX());
	cx = x + w / 2;
	cy = y + h / 2;
	Sprite::UpdateCollisionBox(x, y, w, h, cx, cy);

}
Esempio n. 13
0
void RuntimeSpriteObject::GetPropertyForDebugger(std::size_t propertyNb, gd::String & name, gd::String & value) const
{
    if      ( propertyNb == 0 ) {name = _("Animation");     value = gd::String::From(GetCurrentAnimation());}
    else if ( propertyNb == 1 ) {name = _("Direction");     value = gd::String::From(GetCurrentDirection());}
    else if ( propertyNb == 2 ) {name = _("Image");         value = gd::String::From(GetSpriteNb());}
    else if ( propertyNb == 3 ) {name = _("Opacity");       value = gd::String::From(GetOpacity());}
    else if ( propertyNb == 4 ) {name = _("Blend mode");   if ( blendMode == 0) value = "0 (Alpha)";
                                                                    else if ( blendMode == 1) value = "1 (Add)";
                                                                    else if ( blendMode == 2) value = "2 (Multiply)";
                                                                    else if ( blendMode == 3) value = "3 (None)";}
    else if ( propertyNb == 5 ) {name = _("X Scale");       value = gd::String::From(GetScaleX());}
    else if ( propertyNb == 6 ) {name = _("Y Scale");       value = gd::String::From(GetScaleY());}
}
Esempio n. 14
0
bool FieldView::DrawDot(const Coordinates& coords){
    window=get_window();        //get pointer to parent window

    //we draw only if parent window exists and if dot is colored
    if(window && field->GetColor(coords)!=NONE){
        //getting coords of point
        const double xc = (coords.GetX() + 1) * CELL_SIZE * GetScaleX();
        const double yc = (coords.GetY() + 1) * CELL_SIZE * GetScaleY();

        //preparing context
        cr = window->create_cairo_context();
        if(cr){//if pointer to contest is not NULL
            allocation = get_allocation();
            double awidth = allocation.get_width();
            double aheight = allocation.get_height();

            cr->rectangle(0.0, 0.0, awidth, aheight);
            cr->clip();

            //choose color
            switch(field->GetColor(coords)){
                case RED:
                    cr->set_source_rgb(1.0, 0.0, 0.0);
                    break;
                case BLUE:
                    cr->set_source_rgb(0.0, 0.0, 1.0);
                    break;
                default:
                    return false;
            }

            //setting line width and draw circle
            cr->set_line_width(GetScaleX() * 2.5);
            //this will draw a circle, but we've got to fat lines and this circle will be like a big fat dot
            cr->arc(xc, yc, GetScaleX(), 0.0, 2 * M_PI);

            cr->stroke();
            return true;
        }
    }
    return false;
}
Esempio n. 15
0
/** Renders SVG to bitmap image */
wxImage wxSVGDocument::Render(int width, int height, const wxSVGRect* rect, bool preserveAspectRatio, bool alpha,
		wxProgressDialog* progressDlg) {
	if (!GetRootElement())
		return wxImage();
	
	m_screenCTM = wxSVGMatrix();
	
	if (GetRootElement()->GetWidth().GetBaseVal().GetUnitType() == wxSVG_LENGTHTYPE_UNKNOWN)
		GetRootElement()->SetWidth(wxSVGLength(wxSVG_LENGTHTYPE_PERCENTAGE, 100));
	if (GetRootElement()->GetHeight().GetBaseVal().GetUnitType() == wxSVG_LENGTHTYPE_UNKNOWN)
		GetRootElement()->SetHeight(wxSVGLength(wxSVG_LENGTHTYPE_PERCENTAGE, 100));
	
	if (width == -1 || height == -1) {
		width = (int) GetRootElement()->GetWidth().GetAnimVal();
		height = (int) GetRootElement()->GetHeight().GetAnimVal();
		if (width <= 0 || height <= 0) {
			width = (int) GetRootElement()->GetViewBox().GetAnimVal().GetWidth();
			height = (int) GetRootElement()->GetViewBox().GetAnimVal().GetHeight();
		}
	}
	
	if (GetRootElement()->GetWidth().GetAnimVal().GetUnitType() == wxSVG_LENGTHTYPE_PERCENTAGE) {
		wxSVGAnimatedLength l = GetRootElement()->GetWidth();
		l.GetBaseVal().ToViewportWidth(width);
		if (l.GetBaseVal() != ((const wxSVGAnimatedLength&) l).GetAnimVal())
			l.GetAnimVal().ToViewportWidth(width);
		GetRootElement()->SetWidth(l);
	}
	if (GetRootElement()->GetHeight().GetAnimVal().GetUnitType() == wxSVG_LENGTHTYPE_PERCENTAGE) {
		wxSVGAnimatedLength l = GetRootElement()->GetHeight();
		l.GetBaseVal().ToViewportHeight(height);
		if (l.GetBaseVal() != ((const wxSVGAnimatedLength&) l).GetAnimVal())
			l.GetAnimVal().ToViewportHeight(height);
		GetRootElement()->SetHeight(l);
	}
	
	// scale it to fit in
	m_scale = 1;
	m_scaleY = -1; // == m_scale
	if (GetRootElement()->GetWidth().GetAnimVal() > 0 && GetRootElement()->GetHeight().GetAnimVal() > 0) {
		if (preserveAspectRatio) {
			m_scale = width / GetRootElement()->GetWidth().GetAnimVal();
			if (m_scale > height / GetRootElement()->GetHeight().GetAnimVal())
				m_scale = height / GetRootElement()->GetHeight().GetAnimVal();
			m_screenCTM = m_screenCTM.Scale(m_scale);

			width = (int) (m_scale * GetRootElement()->GetWidth().GetAnimVal());
			height = (int) (m_scale * GetRootElement()->GetHeight().GetAnimVal());
		} else {
			m_scale = width / GetRootElement()->GetWidth().GetAnimVal();
			m_scaleY = height / GetRootElement()->GetHeight().GetAnimVal();
			m_screenCTM = m_screenCTM.ScaleNonUniform(m_scale, m_scaleY);
		}
	}
	
	// render only rect if specified
	if (rect && !rect->IsEmpty()) {
		m_screenCTM = m_screenCTM.Translate(-rect->GetX(), -rect->GetY());
		if (rect->GetWidth() * GetScaleX() < width)
			width = (int) (rect->GetWidth() * GetScaleX());
		if (rect->GetHeight() * GetScaleY() < height)
			height = (int) (rect->GetHeight() * GetScaleY());
	}
	
	// render
	m_canvas->Init(width, height, alpha);
	if (!alpha)
		m_canvas->Clear(*wxWHITE);
	GetCanvas()->RenderElement(GetRootElement(), rect, &m_screenCTM, &GetRootElement()->GetStyle(), NULL, NULL,
			progressDlg);

	return m_canvas->GetImage();
}
Esempio n. 16
0
INLINE void Button::UpdateLabel()
{
	if (bLabelAutoUpdate)
	{
		cLabel.SetRotation(GetRotation());
		cLabel.SetScaleX(GetScaleX());
		cLabel.SetScaleY(GetScaleY());
		cLabel.SetLocalX(GetLocalX());
		cLabel.SetLocalY(GetLocalY());
	}

	cLabel.SetY(0.0f);
	switch (eLabelVAlignment)
	{
		case VerticalAlignTop:
		{
		}
		break;

		case VerticalAlignCenter:
		{
			cLabel.SetY((this->GetHeight() - cLabel.GetHeight()) / 2.0f);
		}
		break;

		case VerticalAlignBottom:
		{
			cLabel.SetY(this->GetHeight() - cLabel.GetHeight());
		}
		break;

		default:
			cLabel.SetY(fLabelOffsetY);
		break;
	}

	cLabel.SetX(0.0f);
	switch (eLabelHAlignment)
	{
		case HorizontalAlignLeft:
		{
		}
		break;

		case HorizontalAlignCenter:
		{
			cLabel.SetX((this->GetWidth() - cLabel.GetWidth()) / 2.0f);
		}
		break;

		case HorizontalAlignRight:
		{
			cLabel.SetX(this->GetWidth() - cLabel.GetWidth());
		}
		break;

		default:
			cLabel.SetX(fLabelOffsetX);
		break;
	}
}
Esempio n. 17
0
bool Map::CompileS3D(
	std::vector<EQEmu::S3D::WLDFragment> &zone_frags,
	std::vector<EQEmu::S3D::WLDFragment> &zone_object_frags,
	std::vector<EQEmu::S3D::WLDFragment> &object_frags
	)
{
	collide_verts.clear();
	collide_indices.clear();
	non_collide_verts.clear();
	non_collide_indices.clear();
	current_collide_index = 0;
	current_non_collide_index = 0;
	collide_vert_to_index.clear();
	non_collide_vert_to_index.clear();
	map_models.clear();
	map_eqg_models.clear();
	map_placeables.clear();

	eqLogMessage(LogTrace, "Processing s3d zone geometry fragments.");
	for(uint32_t i = 0; i < zone_frags.size(); ++i) {
		if(zone_frags[i].type == 0x36) {
			EQEmu::S3D::WLDFragment36 &frag = reinterpret_cast<EQEmu::S3D::WLDFragment36&>(zone_frags[i]);
			auto model = frag.GetData();
		
			auto &mod_polys = model->GetPolygons();
			auto &mod_verts = model->GetVertices();

			for (uint32_t j = 0; j < mod_polys.size(); ++j) {
				auto &current_poly = mod_polys[j];
				auto v1 = mod_verts[current_poly.verts[0]];
				auto v2 = mod_verts[current_poly.verts[1]];
				auto v3 = mod_verts[current_poly.verts[2]];

				float t = v1.pos.x;
				v1.pos.x = v1.pos.y;
				v1.pos.y = t;

				t = v2.pos.x;
				v2.pos.x = v2.pos.y;
				v2.pos.y = t;

				t = v3.pos.x;
				v3.pos.x = v3.pos.y;
				v3.pos.y = t;

				if(current_poly.flags == 0x10)
					AddFace(v1.pos, v2.pos, v3.pos, false);
				else
					AddFace(v1.pos, v2.pos, v3.pos, true);
			}
		}
	}

	eqLogMessage(LogTrace, "Processing zone placeable fragments.");
	std::vector<std::pair<std::shared_ptr<EQEmu::Placeable>, std::shared_ptr<EQEmu::S3D::Geometry>>> placables;
	std::vector<std::pair<std::shared_ptr<EQEmu::Placeable>, std::shared_ptr<EQEmu::S3D::SkeletonTrack>>> placables_skeleton;
	for (uint32_t i = 0; i < zone_object_frags.size(); ++i) {
		if (zone_object_frags[i].type == 0x15) {
			EQEmu::S3D::WLDFragment15 &frag = reinterpret_cast<EQEmu::S3D::WLDFragment15&>(zone_object_frags[i]);
			auto plac = frag.GetData();

			if(!plac)
			{
				eqLogMessage(LogWarn, "Placeable entry was not found.");
				continue;
			}

			bool found = false;
			for (uint32_t o = 0; o < object_frags.size(); ++o) {
				if (object_frags[o].type == 0x14) {
					EQEmu::S3D::WLDFragment14 &obj_frag = reinterpret_cast<EQEmu::S3D::WLDFragment14&>(object_frags[o]);
					auto mod_ref = obj_frag.GetData();

					if(mod_ref->GetName().compare(plac->GetName()) == 0) {
						found = true;

						auto &frag_refs = mod_ref->GetFrags();
						for (uint32_t m = 0; m < frag_refs.size(); ++m) {
							if (object_frags[frag_refs[m] - 1].type == 0x2D) {
								EQEmu::S3D::WLDFragment2D &r_frag = reinterpret_cast<EQEmu::S3D::WLDFragment2D&>(object_frags[frag_refs[m] - 1]);
								auto m_ref = r_frag.GetData();

								EQEmu::S3D::WLDFragment36 &mod_frag = reinterpret_cast<EQEmu::S3D::WLDFragment36&>(object_frags[m_ref]);
								auto mod = mod_frag.GetData();
								placables.push_back(std::make_pair(plac, mod));
							}
							else if (object_frags[frag_refs[m] - 1].type == 0x11) {
								EQEmu::S3D::WLDFragment11 &r_frag = reinterpret_cast<EQEmu::S3D::WLDFragment11&>(object_frags[frag_refs[m] - 1]);
								auto s_ref = r_frag.GetData();

								EQEmu::S3D::WLDFragment10 &skeleton_frag = reinterpret_cast<EQEmu::S3D::WLDFragment10&>(object_frags[s_ref]);
								auto skele = skeleton_frag.GetData();
								
								placables_skeleton.push_back(std::make_pair(plac, skele));
							}
						}

						break;
					}
				}
			}

			if(!found) {
				eqLogMessage(LogWarn, "Could not find model for placeable %s", plac->GetName().c_str());
			}
		}
	}

	eqLogMessage(LogTrace, "Processing s3d placeables.");
	size_t pl_sz = placables.size();
	for(size_t i = 0; i < pl_sz; ++i) {
		auto plac = placables[i].first;
		auto model = placables[i].second;

		auto &mod_polys = model->GetPolygons();
		auto &mod_verts = model->GetVertices();

		float offset_x = plac->GetX();
		float offset_y = plac->GetY();
		float offset_z = plac->GetZ();

		float rot_x = plac->GetRotateX() * 3.14159f / 180.0f;
		float rot_y = plac->GetRotateY() * 3.14159f / 180.0f;
		float rot_z = plac->GetRotateZ() * 3.14159f / 180.0f;

		float scale_x = plac->GetScaleX();
		float scale_y = plac->GetScaleY();
		float scale_z = plac->GetScaleZ();
	
		if (map_models.count(model->GetName()) == 0) {
			map_models[model->GetName()] = model;
		}
		std::shared_ptr<EQEmu::Placeable> gen_plac(new EQEmu::Placeable());
		gen_plac->SetFileName(model->GetName());
		gen_plac->SetLocation(offset_x, offset_y, offset_z);
		//y rotation seems backwards on s3ds, probably cause of the weird coord system they used back then
		//x rotation might be too but there are literally 0 x rotated placeables in all the s3ds so who knows
		gen_plac->SetRotation(rot_x, -rot_y, rot_z);
		gen_plac->SetScale(scale_x, scale_y, scale_z);
		map_placeables.push_back(gen_plac);

		eqLogMessage(LogTrace, "Adding placeable %s at (%f, %f, %f)", model->GetName().c_str(), offset_x, offset_y, offset_z);
	}

	eqLogMessage(LogTrace, "Processing s3d animated placeables.");
	pl_sz = placables_skeleton.size();
	for (size_t i = 0; i < pl_sz; ++i) {
		auto &plac = placables_skeleton[i].first;
		
		auto &bones = placables_skeleton[i].second->GetBones();

		if(bones.size() > 0) 
		{
			float offset_x = plac->GetX();
			float offset_y = plac->GetY();
			float offset_z = plac->GetZ();

			float rot_x = plac->GetRotateX() * 3.14159f / 180.0f;
			float rot_y = plac->GetRotateY() * 3.14159f / 180.0f;
			float rot_z = plac->GetRotateZ() * 3.14159f / 180.0f;

			float scale_x = plac->GetScaleX();
			float scale_y = plac->GetScaleY();
			float scale_z = plac->GetScaleZ();
			TraverseBone(bones[0], glm::vec3(offset_x, offset_y, offset_z), glm::vec3(rot_x, rot_y, rot_z), glm::vec3(scale_x, scale_y, scale_z));
		}
	}

	return true;
}