error_e parseTriangleBlock(char *start, std::vector<rpm_triangle_t> &tris, std::vector<std::string> &textures, std::vector<int> &parentBones) { static const char triBlockStart[] = "\ntriangles\n"; start = strstr( start, triBlockStart ); if(!start) return ERR_CORRUPT_FILE; start += strlen(triBlockStart); while(true) { //read texture name char texname[256]; start = CopyUntilOccurenceOfChar(texname, start, "\n"); if( strcmp(texname, "end") == 0 ) break; //Get texture id int texId = getTextureIndex(textures, texname); if( texId < 0 ) { textures.push_back(std::string(texname)); texId = textures.size()-1; } start = parseTriangle(start, tris, texId, parentBones); } return ERR_NONE; }
int ThingType::getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase) { if(m_null) return 0; getTexture(animationPhase); // we must calculate it anyway. int frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern); Size size = m_texturesFramesOriginRects[animationPhase][frameIndex].size() - m_texturesFramesOffsets[animationPhase][frameIndex].toSize(); return std::max<int>(size.width(), size.height()); }
void ThingType::draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, LightView *lightView) { if(m_null) return; if(animationPhase >= m_animationPhases) return; const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects. if(!texture) return; uint frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern); if(frameIndex >= m_texturesFramesRects[animationPhase].size()) return; Point textureOffset; Rect textureRect; if(scaleFactor != 1.0f) { textureRect = m_texturesFramesOriginRects[animationPhase][frameIndex]; } else { textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex]; textureRect = m_texturesFramesRects[animationPhase][frameIndex]; } Rect screenRect(dest + (textureOffset - m_displacement - (m_size.toPoint() - Point(1, 1)) * 32) * scaleFactor, textureRect.size() * scaleFactor); bool useOpacity = m_opacity < 1.0f; if(useOpacity) g_painter->setColor(Color(1.0f,1.0f,1.0f,m_opacity)); g_painter->drawTexturedRect(screenRect, texture, textureRect); if(useOpacity) g_painter->setColor(Color::white); if(lightView && hasLight()) { Light light = getLight(); if(light.intensity > 0) lightView->addLightSource(screenRect.center(), scaleFactor, light); } }
double getTexcoordY(block iblock, ubyte side) { //return (int((getTextureIndex(iblock, side) - 1) / (BLOCKTEXTURE_SIZE / (double)BLOCKTEXTURE_UNITSIZE)))*(BLOCKTEXTURE_UNITSIZE / (double)BLOCKTEXTURE_SIZE); return ((getTextureIndex(iblock, side) - 1) >> 3) / 8.0; }
double getTexcoordX(block iblock, ubyte side) { //return ((getTextureIndex(iblock, side) - 1) % (BLOCKTEXTURE_SIZE / BLOCKTEXTURE_UNITSIZE))*(BLOCKTEXTURE_UNITSIZE / (double)BLOCKTEXTURE_SIZE); return ((getTextureIndex(iblock, side) - 1) & 7) / 8.0; }
const TexturePtr& ThingType::getTexture(int animationPhase) { TexturePtr& animationPhaseTexture = m_textures[animationPhase]; if(!animationPhaseTexture) { bool useCustomImage = false; if(animationPhase == 0 && !m_customImage.empty()) useCustomImage = true; // we don't need layers in common items, they will be pre-drawn int textureLayers = 1; int numLayers = m_layers; if(m_category == ThingCategoryCreature && numLayers >= 2) { // 5 layers: outfit base, red mask, green mask, blue mask, yellow mask textureLayers = 5; numLayers = 5; } int indexSize = textureLayers * m_numPatternX * m_numPatternY * m_numPatternZ; Size textureSize = getBestTextureDimension(m_size.width(), m_size.height(), indexSize); ImagePtr fullImage; if(useCustomImage) fullImage = Image::load(m_customImage); else fullImage = ImagePtr(new Image(textureSize * Otc::TILE_PIXELS)); m_texturesFramesRects[animationPhase].resize(indexSize); m_texturesFramesOriginRects[animationPhase].resize(indexSize); m_texturesFramesOffsets[animationPhase].resize(indexSize); for(int z = 0; z < m_numPatternZ; ++z) { for(int y = 0; y < m_numPatternY; ++y) { for(int x = 0; x < m_numPatternX; ++x) { for(int l = 0; l < numLayers; ++l) { bool spriteMask = (m_category == ThingCategoryCreature && l > 0); int frameIndex = getTextureIndex(l % textureLayers, x, y, z); Point framePos = Point(frameIndex % (textureSize.width() / m_size.width()) * m_size.width(), frameIndex / (textureSize.width() / m_size.width()) * m_size.height()) * Otc::TILE_PIXELS; if(!useCustomImage) { for(int h = 0; h < m_size.height(); ++h) { for(int w = 0; w < m_size.width(); ++w) { uint spriteIndex = getSpriteIndex(w, h, spriteMask ? 1 : l, x, y, z, animationPhase); ImagePtr spriteImage = g_sprites.getSpriteImage(m_spritesIndex[spriteIndex]); if(spriteImage) { if(spriteMask) { static Color maskColors[] = { Color::red, Color::green, Color::blue, Color::yellow }; spriteImage->overwriteMask(maskColors[l - 1]); } Point spritePos = Point(m_size.width() - w - 1, m_size.height() - h - 1) * Otc::TILE_PIXELS; fullImage->blit(framePos + spritePos, spriteImage); } } } } Rect drawRect(framePos + Point(m_size.width(), m_size.height()) * Otc::TILE_PIXELS - Point(1,1), framePos); for(int x = framePos.x; x < framePos.x + m_size.width() * Otc::TILE_PIXELS; ++x) { for(int y = framePos.y; y < framePos.y + m_size.height() * Otc::TILE_PIXELS; ++y) { uint8 *p = fullImage->getPixel(x,y); if(p[3] != 0x00) { drawRect.setTop (std::min<int>(y, (int)drawRect.top())); drawRect.setLeft (std::min<int>(x, (int)drawRect.left())); drawRect.setBottom(std::max<int>(y, (int)drawRect.bottom())); drawRect.setRight (std::max<int>(x, (int)drawRect.right())); } } } m_texturesFramesRects[animationPhase][frameIndex] = drawRect; m_texturesFramesOriginRects[animationPhase][frameIndex] = Rect(framePos, Size(m_size.width(), m_size.height()) * Otc::TILE_PIXELS); m_texturesFramesOffsets[animationPhase][frameIndex] = drawRect.topLeft() - framePos; } } } } animationPhaseTexture = TexturePtr(new Texture(fullImage, true)); animationPhaseTexture->setSmooth(true); } return animationPhaseTexture; }
double getTexcoordX(item item, ubyte side) { if (isBlock(item)) //如果为方块 return (getTextureIndex(item, side) & 7) / 8.0; else return NULLBLOCK; }
double getTexcoordY(block iblock, ubyte side) { return ((getTextureIndex(iblock, side) - 1) >> 3) / 8.0; }