bool MaterialCompiler::serialize(Node *n, const QList<NodeLink *> &links, QString &typeName) { QMap<Node *, CompiledNodeData>::iterator it = datas.find(n); if(it != datas.end()) { typeName = it.value().type; return true; } else { it = datas.insert(n, {getUniqueId(), QString()}); } QList<NodeLink *> endings; for(NodeLink *l : links) { if(l->getEnd()->getParent() == n) { endings.append(l); } } uint components = n->getIns().size(); QString generic = "generic"; for(NodeLink *l : endings) { QString tpe; if(!serialize(l->getStart()->getParent(), links, tpe)) { return false; } QString type = maxType(tpe, l->getStart()->getData().toMap()["type"].toString()); components = components + computeComponents(type) - 1; generic = maxType(generic, type); } components = qMax(uint(2), components); if(generic == "generic" && !n->getIns().isEmpty()) { generic = "float"; } QString genericAppend = componentsToShader(components); QMap<Property *, QString> props; for(Property *e : n->getProperties()) { if(!e->getValue().isNull()) { props[e] = toShader(e->getValue()); } } for(NodeLink *l : endings) { NodeOut *start = l->getStart(); NodeIn *end = l->getEnd(); QString var = castFunc(end, generic) + "(" + computeName(start) + ")"; props[end] = var; } if(props.size() != n->getProperties().size()) { err = CompiledMaterial::NullProperty; return false; } QString line = n->getData().toMap()["shader"].toString(); if(line.contains(QRegExp("\\bgenericAppend\\b")) && components > 4) { err = CompiledMaterial::InvalidVector; return false; } it.value().type = typeName = line.indexOf(QRegExp("\\bgeneric\\b")) < line.indexOf(QRegExp("\\bgenericAppend\\b")) ? genericAppend : generic; // <<<<< ??? line = line.replace(QRegExp("\\bgeneric\\b"), generic); line = line.replace(QRegExp("\\bgenericAppend\\b"), genericAppend); for(NodeOut *o : n->getOuts()) { QString arg = o->getData().toMap()["arg"].toString(); line = line.replace(QRegExp("\\b" + arg + "\\b"), computeName(o)); } for(auto it = props.cbegin(); it != props.cend(); it++) { Property *prop = it.key(); QString arg = prop->getData().toMap()["arg"].toString(); line = line.replace(QRegExp("\\b" + arg + "\\b"), it.value()); } shader += line + "\n"; return true; }
ShadowBench(bool transparent, bool forceGeometric) : fTransparent(transparent) , fForceGeometric(forceGeometric) { computeName("shadows"); }