void ImposterNode::GetOOBBoxScreenCoords(Entity * node, const Matrix4 & mvp, AABBox3 & screenBounds) { const Rect & viewport = RenderManager::Instance()->GetViewport(); MeshInstanceNode * mesh = dynamic_cast<MeshInstanceNode*>(node); if (mesh) { Vector3 corners[8]; Vector3 screenVertices[8]; mesh->GetBoundingBox().GetCorners(corners); const Matrix4 & worldTransform = mesh->GetWorldTransform(); for (int32 k = 0; k < 8; ++k) { Vector4 pv(corners[k]); pv = pv * worldTransform; pv = pv * mvp; pv.x = (viewport.dx * 0.5f) * (1.f + pv.x/pv.w) + viewport.x; pv.y = (viewport.dy * 0.5f) * (1.f + pv.y/pv.w) + viewport.y; pv.z = (pv.z/pv.w + 1.f) * 0.5f; screenVertices[k] = Vector3(pv.x, pv.y, pv.z); screenBounds.AddPoint(screenVertices[k]); } } int32 count = node->GetChildrenCount(); for (int32 i = 0; i < count; ++i) { GetOOBBoxScreenCoords(node->GetChild(i), mvp, screenBounds); } }
void MeshInstancePropertyControl::OnComboIndexChanged(PropertyList *forList, const String &forKey, int32 newItemIndex, const String &newItemKey) { if(forKey[0] == '#') { int32 index = GetIndexFromKey(forKey); MeshInstanceNode *mesh = dynamic_cast<MeshInstanceNode *> (currentSceneNode); mesh->ReplaceMaterial(materials[newItemIndex], index); UpdateFieldsForCurrentNode(); } NodesPropertyControl::OnComboIndexChanged(forList, forKey, newItemIndex, newItemKey); }
void QuadTree::BuildRecursive(QuadTreeNode * node, List<MeshInstanceNode*> & meshNodes) { cache.Reset(); //meshNodes AABBox3 bbox = node->GetBoundingBox(); AABBox3 childBoxes[4]; Vector3 halfSize = (bbox.max - bbox.min) / 2.0f; childBoxes[0] = AABBox3(Vector3(bbox.min.x, bbox.min.y, bbox.min.z), Vector3(bbox.min.x + halfSize.x, bbox.min.y + halfSize.y, bbox.max.z)); childBoxes[1] = AABBox3(Vector3(bbox.min.x + halfSize.x, bbox.min.y, bbox.min.z), Vector3(bbox.max.x, bbox.min.y + halfSize.y, bbox.max.z)); childBoxes[2] = AABBox3(Vector3(bbox.min.x, bbox.min.y + halfSize.y, bbox.min.z), Vector3(bbox.min.x + halfSize.x, bbox.max.y, bbox.max.z)); childBoxes[3] = AABBox3(Vector3(bbox.min.x + halfSize.x, bbox.min.y + halfSize.y, bbox.min.z), Vector3(bbox.max.x, bbox.max.y, bbox.max.z)); AABBox3 realChildBox[4]; int32 childCount[4] = {0, 0, 0, 0}; List<MeshInstanceNode*> childLists[4]; for (List<MeshInstanceNode*>::iterator it = meshNodes.begin(); it != meshNodes.end();) { MeshInstanceNode * mesh = *it; bool nodeIn = false; for (int k = 0; k < 4; ++k) { const AABBox3 & bbox = mesh->GetWTMaximumBoundingBox(); if (childBoxes[k].IsInside(bbox)) { childCount[k]++; childLists[k].push_back(mesh); realChildBox[k].AddAABBox(bbox); nodeIn = true; break; } } if (nodeIn) { it = meshNodes.erase(it); }else { it++; } } //for (each new node where number of nodes inside is not 0 build recursively) for (int k = 0; k < 4; ++k) { if (childCount[k] > 0) { nodeCount++; node->children[k] = cache.New(); node->children[k]->SetBoundingBox(realChildBox[k]); BuildRecursive(node->children[k], childLists[k]); } } // all objects that are not in childs remains in this node for (List<MeshInstanceNode*>::iterator it = meshNodes.begin(); it != meshNodes.end(); ++it) { node->objectsInside.push_back(SafeRetain(*it)); } }
void MeshInstancePropertyControl::ReadFrom(Entity * sceneNode) { NodesPropertyControl::ReadFrom(sceneNode); MeshInstanceNode *mesh = dynamic_cast<MeshInstanceNode *> (sceneNode); DVASSERT(mesh); propertyList->AddSection("property.meshinstance.meshinstance", GetHeaderState("property.meshinstance.meshinstance", true)); //BBOX AABBox3 bbox = mesh->GetBoundingBox(); AABBox3 transformedBox; bbox.GetTransformedBox(mesh->GetWorldTransform(), transformedBox); propertyList->AddStringProperty("property.meshinstance.bboxmin", PropertyList::PROPERTY_IS_READ_ONLY); propertyList->AddStringProperty("property.meshinstance.bboxmax", PropertyList::PROPERTY_IS_READ_ONLY); propertyList->SetStringPropertyValue("property.meshinstance.bboxmin", Format("%0.2f, %0.2f, %0.2f", transformedBox.min.x, transformedBox.min.y, transformedBox.min.z)); propertyList->SetStringPropertyValue("property.meshinstance.bboxmax", Format("%0.2f, %0.2f, %0.2f", transformedBox.max.x, transformedBox.max.y, transformedBox.max.z)); materials.clear(); materialNames.clear(); if(workingScene) { workingScene->GetDataNodes(materials); } int32 matCount = (int32)materials.size(); for(int32 i = 0; i < matCount; ++i) { Material *mat = materials[i]; materialNames.push_back(mat->GetName()); } Vector<PolygonGroupWithMaterial*> polygroups = mesh->GetPolygonGroups(); for(int32 i = 0; i < (int32)polygroups.size(); ++i) { PolygonGroup *pg = polygroups[i]->GetPolygonGroup(); String fieldName = Format("PolygonGroup #%d", i); propertyList->AddSection(fieldName, GetHeaderState(fieldName, true)); int32 vertexFormat = pg->GetFormat(); String keyPrefix = Format("#%d", i); propertyList->AddBoolProperty(keyPrefix + ". fmt.NORMAL", PropertyList::PROPERTY_IS_EDITABLE); propertyList->SetBoolPropertyValue(keyPrefix + ". fmt.NORMAL", 0 != (vertexFormat & EVF_NORMAL)); propertyList->AddBoolProperty(keyPrefix + ". fmt.COLOR", PropertyList::PROPERTY_IS_EDITABLE); propertyList->SetBoolPropertyValue(keyPrefix + ". fmt.COLOR", 0 != (vertexFormat & EVF_COLOR)); propertyList->AddBoolProperty(keyPrefix + ". fmt.TEXCOORD0", PropertyList::PROPERTY_IS_EDITABLE); propertyList->SetBoolPropertyValue(keyPrefix + ". fmt.TEXCOORD0", 0 != (vertexFormat & EVF_TEXCOORD0)); propertyList->AddBoolProperty(keyPrefix + ". fmt.TEXCOORD1", PropertyList::PROPERTY_IS_EDITABLE); propertyList->SetBoolPropertyValue(keyPrefix + ". fmt.TEXCOORD1", 0 != (vertexFormat & EVF_TEXCOORD1)); propertyList->AddBoolProperty(keyPrefix + ". fmt.TEXCOORD2", PropertyList::PROPERTY_IS_EDITABLE); propertyList->SetBoolPropertyValue(keyPrefix + ". fmt.TEXCOORD2", 0 != (vertexFormat & EVF_TEXCOORD2)); propertyList->AddBoolProperty(keyPrefix + ". fmt.TEXCOORD3", PropertyList::PROPERTY_IS_EDITABLE); propertyList->SetBoolPropertyValue(keyPrefix + ". fmt.TEXCOORD3", 0 != (vertexFormat & EVF_TEXCOORD3)); propertyList->AddBoolProperty(keyPrefix + ". fmt.TANGENT", PropertyList::PROPERTY_IS_EDITABLE); propertyList->SetBoolPropertyValue(keyPrefix + ". fmt.TANGENT", 0 != (vertexFormat & EVF_TANGENT)); propertyList->AddBoolProperty(keyPrefix + ". fmt.BINORMAL", PropertyList::PROPERTY_IS_EDITABLE); propertyList->SetBoolPropertyValue(keyPrefix + ". fmt.BINORMAL", 0 != (vertexFormat & EVF_BINORMAL)); propertyList->AddBoolProperty(keyPrefix + ". fmt.JOINTWEIGHT", PropertyList::PROPERTY_IS_EDITABLE); propertyList->SetBoolPropertyValue(keyPrefix + ". fmt.JOINTWEIGHT", 0 != (vertexFormat & EVF_JOINTWEIGHT)); propertyList->AddIntProperty(keyPrefix + ".lightmap.size"); propertyList->SetIntPropertyValue(keyPrefix + ".lightmap.size", currentSceneNode->GetCustomProperties()->GetInt32(keyPrefix + ".lightmap.size", 128)); if(matCount && !createNodeProperties) { String comboName = keyPrefix + ". Material"; propertyList->AddComboProperty(comboName, materialNames); if(polygroups[i]->GetMaterial()) { String meshMatName = polygroups[i]->GetMaterial()->GetName(); for(int32 iMat = 0; iMat < (int32)materials.size(); ++iMat) { if(meshMatName == materialNames[iMat]) { propertyList->SetComboPropertyIndex(comboName, iMat); break; } } } else { propertyList->SetComboPropertyIndex(comboName, 0); } propertyList->AddMessageProperty("property.meshinstance.editmaterial", Message(this, &MeshInstancePropertyControl::OnGo2Materials, polygroups[i]->GetMaterial())); } propertyList->AddMessageProperty("property.meshinstance.showtriangles", Message(this, &MeshInstancePropertyControl::OnShowTexture, pg)); } propertyList->AddSection("property.meshinstance.dynamicshadow", GetHeaderState("property.meshinstance.dynamicshadow", true)); propertyList->AddBoolProperty("property.meshinstance.dynamicshadow.enable"); propertyList->SetBoolPropertyValue("property.meshinstance.dynamicshadow.enable", currentSceneNode->GetCustomProperties()->GetBool("property.meshinstance.dynamicshadow.enable", false)); propertyList->AddMessageProperty("property.meshinstance.dynamicshadow.converttovolume", Message(this, &MeshInstancePropertyControl::OnConvertToShadowVolume)); }