void tSpriteBatch::draw(uint8_t z, tTexture* t, const tRectf& dest, const tOptional<tRectf>& src, const tColor4f& c, float rotz, const tPoint2f& origin) { std::pair<uint8_t, tTexture*> key(z, t); Value& ref = mSteps[key]; size_t curIndex = ref.mVerts.size(); //Calculate position coords FourPoints(ref.mVerts, dest); float co = cosf(rotz); float s = sinf(rotz); tMatrix2x2f rotMatrix(tVector2f( co, -s), tVector2f( s, co)); for (size_t i = 0; i < 4; i++) { tVector2f in = ref.mVerts[curIndex + i] - tVector2f(dest.location.x, dest.location.y) - tVector2f(origin.x, origin.y); tVector2f out = in * rotMatrix; ref.mVerts[curIndex + i] = out + tVector2f(dest.location.x, dest.location.y); } //Calculate texture coords if (src) { tDimension2f texSize = tDimension2f(t->getSize().x, t->getSize().y); FourPoints(ref.mTexCoords, tRectf((float)src->location.x / texSize.width, (float)src->location.y / texSize.height, (float)src->size.width / texSize.width, (float)src->size.height / texSize.height)); } else { FourPoints(ref.mTexCoords, tRectf(0, 0, (float)t->getSurfaceSize().width / (float)t->getSize().width, (float)t->getSurfaceSize().height / (float)t->getSize().height)); } //Calculate colors ref.mColors.push_back(c); ref.mColors.push_back(c); ref.mColors.push_back(c); ref.mColors.push_back(c); //Calculate indices SixIndices(ref.mIndices, (uint16_t)curIndex); }
void ParticleManager::createParticle(tTexture* texture, const tVector2f& position, const tColor4f& tint, float duration, float scale, const ParticleState& state, float theta) { createParticle(texture, position, tint, duration, tVector2f(scale), state, theta); }
tVector2f MathUtil::fromPolar(float angle, float magnitude) { return tVector2f((float)cosf(angle), (float)sinf(angle)) * magnitude; }
tVector2f MathUtil::catmullRom(const tVector2f& value1, const tVector2f& value2, const tVector2f& value3, const tVector2f& value4, float amount) { return tVector2f(MathUtil::catmullRom(value1.x, value2.x, value3.x, value4.x, amount), MathUtil::catmullRom(value1.y, value2.y, value3.y, value4.y, amount)); }
void Entity::draw(tSpriteBatch* spriteBatch) { spriteBatch->draw(1, mImage, tPoint2f((int32_t)mPosition.x, (int32_t)mPosition.y), tOptional<tRectf>(), mColor, mOrientation, getSize() / 2, tVector2f(1,1)); }
bool tBillboardBatch::Commit() { QVector<tVector3f> position; QVector<tVector2f> texCoords; QList<tIndexedImage> images; tWriteLocker lock(&m_BatchLock); //Now texture coordinates only one time tho if( m_xTextureAtlas != 0 ) { QHash<QString, tRectangularTextureCoords> texInfo = m_xTextureAtlas->CoordList(); tVector3d square[] = { tVector3d(-0.5, 0.5, 1.0), tVector3d(-0.5, -0.5, 1.0), tVector3d(0.5, 0.5, 1.0), tVector3d(0.5, -0.5, 1.0) }; for(int j = 0; j < m_Billboards.count(); ++j) { tBillboardBatchItem currentItem = m_Billboards[j]; if (currentItem.xBillboard->IsHidden() == false) { boost::shared_ptr<tBillboard> xGeoBillboard = currentItem.xBillboard; tRectangularTextureCoords coords = texInfo[currentItem.key]; double lowestZ = 0; unsigned int startingIndex = position.size(); unsigned int vertexCount = 6; tVector3d forward = xGeoBillboard->Up().CrossProduct(xGeoBillboard->Right()); forward.Normalize(); tVector2f textureBottomLeft( coords.bottomLeft.x, coords.bottomLeft.y); tVector2f textureBottomRight( coords.bottomRight.x, coords.bottomRight.y); tVector2f textureTopLeft( coords.topLeft.x, coords.topLeft.y); tVector2f textureTopRight( coords.topRight.x, coords.topRight.y); SquareTriangleList( textureTopLeft, textureBottomLeft, textureTopRight, textureBottomRight, texCoords ); tMatrix4d view; Matrix4Translate( view, tVector3d(-m_Offset) ); tVector3d imageOffsetWorldRight = xGeoBillboard->ScaleFactor() * xGeoBillboard->ImagePixelOffsetX() * xGeoBillboard->Right(); tVector3d imageOffsetWorldUp = xGeoBillboard->ScaleFactor() * xGeoBillboard->ImagePixelOffsetY() * -xGeoBillboard->Up(); // Negate up because in pixels space top left is origin tVector3d imageOffsetWorldVector = imageOffsetWorldRight + imageOffsetWorldUp; tMatrix4d imageWorldOffset; Matrix4Translate( imageWorldOffset, imageOffsetWorldVector ); tMatrix4d world = xGeoBillboard->WorldTransform(); tMatrix4d mvMatrix = view * imageWorldOffset * world; tVector3d billboardTopLeft = mvMatrix * square[0]; tVector3d billboardBottomLeft = mvMatrix * square[1]; tVector3d billboardTopRight = mvMatrix * square[2]; tVector3d billboardBottomRight = mvMatrix * square[3]; tVector3f billboardTopLeftF( static_cast<float>(billboardTopLeft.x), static_cast<float>(billboardTopLeft.y), static_cast<float>(billboardTopLeft.z) ); tVector3f billboardBottomLeftF( static_cast<float>(billboardBottomLeft.x), static_cast<float>(billboardBottomLeft.y), static_cast<float>(billboardBottomLeft.z) ); tVector3f billboardTopRightF( static_cast<float>(billboardTopRight.x), static_cast<float>(billboardTopRight.y), static_cast<float>(billboardTopRight.z) ); tVector3f billboardBottomRightF( static_cast<float>(billboardBottomRight.x), static_cast<float>(billboardBottomRight.y), static_cast<float>(billboardBottomRight.z) ); SquareTriangleList( billboardTopLeftF, billboardBottomLeftF, billboardTopRightF, billboardBottomRightF, position ); lowestZ = LowestZOnSquare( billboardTopLeft, billboardBottomLeft, billboardTopRight, billboardBottomRight ); if ( xGeoBillboard->Text().isEmpty() == false ) { tRectangularTextureCoords textCoords = texInfo[ QString("%1 %2").arg(xGeoBillboard->Text()).arg(qHash(xGeoBillboard->TextStyle())) ]; textureBottomLeft = tVector2f( textCoords.bottomLeft.x, textCoords.bottomLeft.y); textureBottomRight = tVector2f( textCoords.bottomRight.x, textCoords.bottomRight.y); textureTopLeft = tVector2f( textCoords.topLeft.x, textCoords.topLeft.y); textureTopRight = tVector2f( textCoords.topRight.x, textCoords.topRight.y); SquareTriangleList( textureTopLeft, textureBottomLeft, textureTopRight, textureBottomRight, texCoords ); tVector3d textPosition = xGeoBillboard->CreateTextOffsetVertex( xGeoBillboard->TextStyle().m_align, xGeoBillboard->Up(), xGeoBillboard->Right(), xGeoBillboard->ScaleFactor(), xGeoBillboard->TextWidth(), xGeoBillboard->TextHeight() ); textPosition += (-forward * xGeoBillboard->ScaleFactor()); tMatrix4d translation; Matrix4Translate( translation, textPosition ); tMatrix4d scale; Matrix4Scale( scale, xGeoBillboard->ScaleFactor() * xGeoBillboard->TextWidth(), xGeoBillboard->ScaleFactor() * xGeoBillboard->TextHeight(), xGeoBillboard->ScaleFactor() ); tMatrix4d world = translation * xGeoBillboard->RotationMatrix() * scale; mvMatrix = view * imageWorldOffset * world; billboardTopLeft = mvMatrix * square[0]; billboardBottomLeft = mvMatrix * square[1]; billboardTopRight = mvMatrix * square[2]; billboardBottomRight = mvMatrix * square[3]; tVector3f billboardTopLeftF( static_cast<float>(billboardTopLeft.x), static_cast<float>(billboardTopLeft.y), static_cast<float>(billboardTopLeft.z) ); tVector3f billboardBottomLeftF( static_cast<float>(billboardBottomLeft.x), static_cast<float>(billboardBottomLeft.y), static_cast<float>(billboardBottomLeft.z) ); tVector3f billboardTopRightF( static_cast<float>(billboardTopRight.x), static_cast<float>(billboardTopRight.y), static_cast<float>(billboardTopRight.z) ); tVector3f billboardBottomRightF( static_cast<float>(billboardBottomRight.x), static_cast<float>(billboardBottomRight.y), static_cast<float>(billboardBottomRight.z) ); SquareTriangleList( billboardTopLeftF, billboardBottomLeftF, billboardTopRightF, billboardBottomRightF, position ); lowestZ = qMin( lowestZ, LowestZOnSquare( billboardTopLeft, billboardBottomLeft, billboardTopRight, billboardBottomRight ) ); vertexCount += 6; } // This portion of code is to keep the billboards from going into the ground. // Throughout the creation of billboards we keep track of the lowest z value // and if it is under zero (land) then you adjust it to stay above ground if ( lowestZ < 0 ) { for ( unsigned int i = 0; i < vertexCount; ++i ) { unsigned int index = startingIndex + i; position[index].z += fabs( static_cast<float>(lowestZ) ); } } } } } bool createNewVertexBuffer = false; if (static_cast<unsigned int>(position.count()) != m_NumVertices) { createNewVertexBuffer = true; } m_NumVertices = position.count(); if( position.isEmpty() == false && texCoords.isEmpty() == false && position.count() == texCoords.count()) { unsigned long positionSize = sizeof(float) * 3 * position.count(); unsigned long texCoordSize = sizeof(float) * 2 * texCoords.count(); boost::shared_ptr<tVertexDescription> xVertexDescription( new tVertexDescription() ); xVertexDescription->AddVertexBufferAttribute( tVertexDescription::eVBAT_Position, tVertexDescription::eVBADT_Float3, 0 ); xVertexDescription->AddVertexBufferAttribute( tVertexDescription::eVBAT_TextureCoord, tVertexDescription::eVBADT_Float2, positionSize ); if (createNewVertexBuffer == true) { boost::shared_ptr<tVertexBuffer> xVertexBuffer = tHardwareBufferFactory::Instance().CreateVertexBuffer( *xVertexDescription, position.count(), tHardwareBuffer::eUsage_StaticWriteOnly, false ); m_xVBAccess.reset( new tVertexBufferAccess(xVertexBuffer, xVertexDescription) ); } m_xVBAccess->Write( tVertexDescription::eVBAT_Position, position.data(), positionSize ); m_xVBAccess->Write( tVertexDescription::eVBAT_TextureCoord, texCoords.data(), texCoordSize ); m_xRenderOperation.reset( new tRenderOperation(tRenderOperation::eRenderType_TriangleList, m_xVBAccess) ); Assert(m_xRenderOperation != 0); return true; } //Assert(0) return false; }