Ejemplo n.º 1
0
void Entity::move(sfld::Vector2f direction, int frameTime, float magnitude){
	EntityList* list = entityManager_->getEntities();
	for (auto& it : *list){
		if (it.get() != this){
			float dist = sfld::Vector2f(it->getPosition() - getPosition()).length();
			if (!it->isWalkthrough()){
				if (dist <= TILE_SIZE*1.5f){ //need accurate collisions here
					MTV mtv(Collision::getCollision(getSprite(), getShape(), it->getSprite(), it->getShape()));
					if (!(mtv.axis == MTV::NONE.axis && mtv.overlap == MTV::NONE.overlap)){;
						//collided
						sfld::Vector2f n = mtv.axis;
						sfld::Vector2f comp_u(0, 0);

						if (direction.dot(n) < 0){
							if (n != sfld::Vector2f(0, 0)){
								comp_u = n * (direction.dot(n) / n.dot(n)); //component of hit axis in dir
							}
						}
						direction = direction - comp_u;
						collided(it.get());
						if (it->getDynamic() == DYNAMIC_STATIC){ //because then it won't resolve its own collisions
							it->collided(this);
						}
					}

				}
			}
			else{//otherwise, it's a circle, and we are only concerned with checking if they touch, no more
				if (dist <= TILE_SIZE*1.5f){
					MTV mtv(Collision::getCollision(getSprite(), getShape(), it->getSprite(), it->getShape()));
					if (!(mtv.axis == MTV::NONE.axis && mtv.overlap == MTV::NONE.overlap)){
						collided(it.get());
						if (it->getDynamic() == DYNAMIC_STATIC){ //because then it won't resolve its own collisions
							it->collided(this);
						}
					}
				}
			}
		}
	}
	if (direction != sf::Vector2f(0, 0) && !rotating_){
		//lastdir = dir;
		sprite_.setRotation(maths::toDegrees(atan2(direction.y, direction.x)));
	}
	doOffset(direction*(float)frameTime*magnitude);
}
Ejemplo n.º 2
0
void ProcessView::onModulesActionTriggered()
{
	// Alternative way: currentIndex().row()
	QModelIndexList indexList = this->selectionModel()->selectedRows();
	unsigned int pid = model()->data(model()->index(indexList.first().row(), 1)).toUInt();
	if (pid >= 0)
	{
		ModulesTableView mtv(pid);
		mtv.exec();
	}
}
Ejemplo n.º 3
0
void LSCompiler::processTypes(ModuleBuildInfo *mbi)
{
    // process the fully qualified type information
    for (UTsize j = 0; j < mbi->getNumSourceFiles(); j++)
    {
        utString filename = mbi->getSourceFilename(j);

        CompilationUnit *cunit = mbi->getCompilationUnit(filename);

        logVerbose("Type Qualifying Visitor %s", cunit->filename.c_str());

        TypeQualifyVisitor tqv(vm);
        tqv.visit(cunit);
    }

    // process the member types, so everything is available once
    // we get to the method code
    for (UTsize j = 0; j < mbi->getNumSourceFiles(); j++)
    {
        utString        filename = mbi->getSourceFilename(j);
        CompilationUnit *cunit   = mbi->getCompilationUnit(filename);

        logVerbose("Type Member Visitor %s", cunit->filename.c_str());

        MemberTypeVisitor mtv(vm, cunit);
        mtv.processMemberTypes();
    }

    // generate type info for method code
    for (UTsize j = 0; j < mbi->getNumSourceFiles(); j++)
    {
        utString        filename = mbi->getSourceFilename(j);
        CompilationUnit *cunit   = mbi->getCompilationUnit(filename);

        logVerbose("Type Visitor %s", cunit->filename.c_str());

        TypeVisitor tv(vm);
        tv.visit(cunit);
    }

    // if we have any compiler errors, dump them and exit
    if (LSCompilerLog::getNumErrors())
    {
        LSCompilerLog::dump();
        exit(EXIT_FAILURE);
    }

    // validate types
    for (UTsize j = 0; j < mbi->getNumSourceFiles(); j++)
    {
        utString filename = mbi->getSourceFilename(j);

        CompilationUnit *cunit = mbi->getCompilationUnit(filename);

        logVerbose("Type Validating %s", cunit->filename.c_str());

        for (UTsize k = 0; k < cunit->classDecls.size(); k++)
        {
            TypeValidator tv(vm, cunit, cunit->classDecls.at(k));
            tv.validate();
        }
    }

    // if we have any compiler errors, dump them and exit
    if (LSCompilerLog::getNumErrors())
    {
        LSCompilerLog::dump();
        exit(EXIT_FAILURE);
    }
}
Ejemplo n.º 4
0
/////////////////////
// static
QVector<QSharedPointer<MetaTypeVariant> >
MarshallRuby::VALUE2MTVariant(VALUE v)
{
    QVector<QSharedPointer<MetaTypeVariant> > rvs(1);
    QSharedPointer<MetaTypeVariant> rv;
    QString str, str2;
    void *ci = NULL;
    QObject *obj = NULL;

    VALUE v1, v2, v3;
    
    switch (TYPE(v)) {
    case T_NONE:  rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant()); break;
    case T_FIXNUM: {
        QVariant num = (int)FIX2INT(v);
        rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant(QMetaType::Int, &num));
    }; break;
    case T_STRING: {
        QVariant str = QString(RSTRING_PTR(v));
        rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant(QMetaType::QString, &str));
    }; break;
    case T_FLOAT: {
        QVariant num = RFLOAT_VALUE(v);
        rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant(QMetaType::Double, &num));
    }; break;
    case T_NIL: {
        QVariant  num = 0;
        rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant(QMetaType::Int, &num));
    }; break;
    case T_TRUE: {
        QVariant ok = true;
        rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant(QMetaType::Bool, &ok));
    }; break;
    case T_FALSE: {
        QVariant ok = false;
        rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant(QMetaType::Bool, &ok));
    }; break;
    case T_OBJECT: {
        str = QString(rb_class2name(RBASIC_CLASS(v)));
        ci = Qom::inst()->getObject(v);
        // obj = dynamic_cast<QObject*>(ci);
        qDebug()<<"unimpl VALUE:"<<str<<ci<<obj;
        // rv = QVariant(QMetaType::VoidStar, ci);
        // rv = QVariant::fromValue(ci);
        QVariant vrv = QVariant::fromValue(ci);
        rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant(QMetaType::VoidStar, &vrv));
    }; break;
    case T_ARRAY: {
        QStringList ary;
        // ary << "a123" << "b3456";
        qDebug()<<RARRAY_LEN(v)<<QT_VERSION;
        for (int i = 0; i < RARRAY_LEN(v); i++) {
            // FIXME: 也可能是对象数组,如Qt5::QString,但toString方法不好用。
            // FIXME: 如,[Qt5::QApplication.translate("MainWindow", "acbc", nil), "efgggggg", "hijjjjjjjj"]
            ary << VALUE2Variant(rb_ary_entry(v, i)).toString();
        }
        // rv = QVariant(ary);
        QVariant vary(ary);
        rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant(QMetaType::QStringList, &vary));
    }; break;
    case T_STRUCT: { // for ruby range
        str = rb_class2name(RBASIC_CLASS(v));
        if (str == "Range") {
            // qDebug()<<"Range is struct???"<<BUILTIN_TYPE(v)
            //         <<rb_class2name(RBASIC_CLASS(v))
            //         <<RSTRUCT_LEN(v);
            v1 = RSTRUCT_GET(v, 0);
            v2 = RSTRUCT_GET(v, 1);
            v3 = RSTRUCT_GET(v, 2);
            // qDebug()<<TYPE(v1)<<TYPE(v2)<<TYPE(v3);
            // qDebug()<<FIX2INT(v1)<<FIX2INT(v2);

            // rv = QVariant(FIX2INT(v1));
            // rvs.append(QVariant(FIX2INT(v2)));
            QVariant num1 = FIX2INT(v1);
            QVariant num2 = FIX2INT(v2);
            rv = QSharedPointer<MetaTypeVariant>(new MetaTypeVariant(QMetaType::Int, &num1));
            QSharedPointer<MetaTypeVariant> mtv(new MetaTypeVariant(QMetaType::Int, &num2));
            rvs.append(mtv);
        } else {
            qDebug()<<"unsupported struct type:"<<str;
        }
    }; break;
    case T_CLASS:
    default:
        qDebug()<<"unknown VALUE type:"<<TYPE(v);
        break;
    }
    
    rvs[0] = rv;
    return (rvs);
}
Ejemplo n.º 5
0
MTV Collision::getCollision(const sf::Sprite& object1,Entity::ENTITY_SHAPE shape1,const sf::Sprite& object2,Entity::ENTITY_SHAPE shape2){
	//Use Separating Axis Theorem to determine whether two objects are overlapping
	//See documentation for full explanation of this algorithm

	//Get the oriented bounding box in world coordinates (includes rotation) of objects
	OBB obb1 = getOBB(object1);
	OBB obb2 = getOBB(object2);
	float rot = object1.getRotation();

	double overlap = LONG_MAX;
	maths::Vector2 smallest(0,0);

	std::vector<maths::Vector2> axis1;
	std::vector<maths::Vector2> axis2;

	maths::Vector2 circleCentre1;
	maths::Vector2 circleCentre2;

	sf::FloatRect gbounds1 = object1.getGlobalBounds();
	sf::FloatRect gbounds2 = object2.getGlobalBounds();
	 
	//Find all the axes to check using SAT based on shapes of objects
	//Works with squares/rectangles or circles
	//Rectangles only need 2 axes because they have 2 sets of parallel lines
	if(shape1 == Entity::SHAPE_CIRCLE && shape2 == Entity::SHAPE_CIRCLE){
		//If both shapes are circles, the only axis needed is the axis between centres of circles
		circleCentre1 = maths::Vector2(gbounds1.left + gbounds1.width / 2, gbounds1.top + gbounds1.height / 2);
		circleCentre2 = maths::Vector2(gbounds2.left + gbounds2.width / 2, gbounds2.top + gbounds2.height / 2);
		axis1.push_back(maths::Vector2(circleCentre1 - circleCentre2).normalise());

	}else if(shape1 != shape2){ //if one shape is circle and one shape is rectangle
		maths::Vector2 circleCentre;
		sf::FloatRect squareRect;
		float rotation;

		//First get the unrotated bounding box and centre of the circle of the 2 objects
		if(shape1 == Entity::SHAPE_CIRCLE){
			circleCentre = maths::Vector2(gbounds1.left + gbounds1.width / 2, gbounds1.top + gbounds1.height / 2);
			circleCentre1 = circleCentre;
			squareRect = getOriginalBoundingBox(object2);
			rotation = object2.getRotation();
		}else if(shape2 == Entity::SHAPE_CIRCLE){
			circleCentre = maths::Vector2(gbounds2.left + gbounds2.width / 2, gbounds2.top + gbounds2.height / 2);
			circleCentre2 = circleCentre;
			squareRect = getOriginalBoundingBox(object1);
			rotation = object1.getRotation();
		}

		maths::Vector2 squareCentre(squareRect.left + squareRect.width / 2, squareRect.top + squareRect.height / 2);
		OBB* square = (shape1 == Entity::SHAPE_SQUARE ? &obb1 : &obb2);
		maths::Vector2 relativeCircleCentre = circleCentre.rotate(-rotation, squareCentre); //get circle centre in relation to the rotated square
		bool vertice = false;
		maths::Vector2 axis;

		maths::Vector2 topLeft(squareRect.left, squareRect.top);
		maths::Vector2 topRight(squareRect.left + squareRect.width, squareRect.top);
		maths::Vector2 botLeft(squareRect.left, squareRect.top + squareRect.height);
		maths::Vector2 botRight(squareRect.left + squareRect.width, squareRect.top + squareRect.height);

		//Get the closest vertex of the rectangle to the circle centre.
		//The axis to check is the vector between these 2 points.
		if(circleCentre.x < topLeft.x){
			if(circleCentre.y < topLeft.y){
				vertice = true;
				axis = topLeft;
			}else if(circleCentre.y >  botLeft.y){
				vertice = true;
				axis = botLeft;
			}else{
				axis = maths::Vector2(topLeft - botLeft).normalise();
			}
		}else if(circleCentre.x > topRight.x){
			if(circleCentre.y < topLeft.y){
				vertice = true;
				axis = topRight;
			}else if(circleCentre.y >  botLeft.y){
				vertice = true;
				axis = botRight;
			}else{
				axis = maths::Vector2(topRight - botRight).normalise();
			}
		}else{
			if(circleCentre.y < topLeft.y){
				axis = maths::Vector2(topRight - topLeft).normalise();
			}else if(circleCentre.y >  botLeft.y){
				axis = maths::Vector2(botLeft - botRight).normalise();
			}else{
				//contains point!
			}
		}

		if(vertice){
			axis1.push_back(maths::Vector2(circleCentre - axis).normalise());
		}else{
			axis1.push_back(maths::Vector2(topRight - topLeft).normalise());
			axis1.push_back(maths::Vector2(topRight - botRight).normalise());
		}
	}else{ //If both shapes are rectangles
		//Get vectors for sides of shapes
		maths::Vector2 Xside1(obb1.bot_left - obb1.bot_right);
		maths::Vector2 Yside1(obb1.top_left - obb1.bot_left);
		maths::Vector2 Xside2(obb2.bot_left - obb2.bot_right);
		maths::Vector2 Yside2(obb2.top_left - obb2.bot_left);

		//Axes requires are perpendicular to the sides of the shape
		//Vector2.perpendicular() normalises for greater accuracy
		axis1.push_back(Xside1.perpendicular());
		axis1.push_back(Yside1.perpendicular());
		axis2.push_back(Xside2.perpendicular());
		axis2.push_back(Yside2.perpendicular());
	}

	//We have all the axes to check.
	//Now find details on collisions with projections.

	for(int i=0;i<axis1.size();i++){
		//Get projection of axis for both shapes
		maths::Vector2 axis = axis1[i];
		Projection projection1 = project(obb1, axis);
		if(shape1 == Entity::SHAPE_CIRCLE){
			float radius = gbounds1.width / 2;
			projection1 = projectCircle(circleCentre1, radius, axis);
		}
		Projection projection2 = project(obb2, axis);
		if (shape2 == Entity::SHAPE_CIRCLE){
			float radius = gbounds2.width / 2;
			projection2 = projectCircle(circleCentre2, radius, axis);
		}

		//If a projection does not overlap, we know the objects do not collide so we can exit the function.
		//Otherwise, the MTV (minimum translation vector required to make the objects not collide) is calculated.

		if(!projection1.overlap(projection2)){
			return MTV::NONE;
		}else{
			//The axis with the smallest overlap is the axis used to calculate MTV, so record it.
			double o = projection1.getOverlap(projection2);
			if(o < overlap){
				overlap = o; //set smallest overlap
				smallest = axis; //set smallest separation vector
			}
		}
	}
	
	//Repeat the same process as above with the other set of axes.
	for(int i=0;i<axis2.size();i++){
		maths::Vector2 axis = axis2[i];
		Projection projection1 = project(obb1, axis);
		if(shape1 == Entity::SHAPE_CIRCLE){
			float radius = gbounds1.width/2;
			projection1 = projectCircle(circleCentre1, radius, axis);
		}
		Projection projection2 = project(obb2,axis);
		if(shape2 == Entity::SHAPE_CIRCLE){
			float radius = gbounds2.width / 2;
			projection2 = projectCircle(circleCentre2, radius, axis);
		}

		if(!projection1.overlap(projection2)){
			return MTV::NONE;
		}else{
			double o = projection1.getOverlap(projection2);
			if(o < overlap){
				overlap = o;
				smallest = axis;
			}
		}
	}
	//Get the vector from the centre of object 2 to the centre of object 1
	maths::Vector2 centre1 = maths::Vector2(gbounds1.left + gbounds1.width / 2, gbounds1.top + gbounds1.height / 2);
	maths::Vector2 centre2 = maths::Vector2(gbounds2.left + gbounds2.width / 2, gbounds2.top + gbounds2.height / 2);
	maths::Vector2 between = centre1 - centre2;
	//If the separation vector is in the opposite direction of 'between', flip it round by negating it
	if(between.dot(smallest) < 0){
		smallest = -smallest;
	}
	MTV mtv(overlap, smallest);
	return mtv;
}