void BasicBoxStacks (DemoEntityManager* const scene) { // load the skybox scene->CreateSkyBox(); CreateLevelMesh (scene, "flatPlane.ngd", 1); // load the scene from a ngd file format #if 0 char fileName[2048]; //GetWorkingFileName ("boxStacks_1.ngd", fileName); //GetWorkingFileName ("boxStacks_3.ngd", fileName); //GetWorkingFileName ("boxStacks.ngd", fileName); //GetWorkingFileName ("pyramid20x20.ngd", fileName); GetWorkingFileName ("pyramid40x40.ngd", fileName); scene->LoadScene (fileName); #else int high = 30; PrimitiveType selection[] = {_BOX_PRIMITIVE, _CYLINDER_PRIMITIVE, _TAPERED_CYLINDER_PRIMITIVE, _REGULAR_CONVEX_HULL_PRIMITIVE}; for (int i = 0; i < 1; i ++) { int index = i % (sizeof (selection) / sizeof (selection[0])); //index = 0; dMatrix shapeMatrix (dRollMatrix(0.5f * 3.14159f)); if (selection[index] == _BOX_PRIMITIVE) { shapeMatrix = dGetIdentityMatrix(); } // BuildPyramid (scene, 10.0f, dVector(-10.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, selection[index], shapeMatrix); BuildPyramid (scene, 10.0f, dVector( 0.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, _BOX_PRIMITIVE); // BuildPyramid (scene, 10.0f, dVector( 10.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, _CYLINDER_PRIMITIVE, dRollMatrix(0.5f * 3.14159f)); // BuildPyramid (scene, 10.0f, dVector( 20.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, _TAPERED_CYLINDER_PRIMITIVE, dRollMatrix(0.5f * 3.14159f)); // BuildPyramid (scene, 10.0f, dVector( 30.0f + i * 4.0f, 0.0f, 0.0f, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high, _REGULAR_CONVEX_HULL_PRIMITIVE, dRollMatrix(0.5f * 3.14159f)); } high = 20; for (int i = 0; i < 1; i ++) { for (int j = 0; j < 1; j ++) { // BuildJenga (scene, 5.0f, dVector(-15.0f + j * 8, 0.0f, 10.0f + i * 8, 0.0f), dVector (0.5f, 0.25f, 1.62f/2.0f, 0.0), high); } } #endif // place camera into position dQuaternion rot; dVector origin (-40.0f, 10.0f, 0.0f, 0.0f); //origin.m_x = -10.0f; origin.m_x = -20.0f; origin.m_y = 8.0f; scene->SetCameraMatrix(rot, origin); // ExportScene (scene->GetNewton(), "../../../media/test1.ngd"); }
dCustomPlayerController* dCustomPlayerControllerManager::CreateController(const dMatrix& location, const dMatrix& localAxis, dFloat mass, dFloat radius, dFloat height, dFloat stepHeight) { NewtonWorld* const world = GetWorld(); dMatrix shapeMatrix(localAxis); shapeMatrix.m_posit = shapeMatrix.m_front.Scale (height * 0.5f); shapeMatrix.m_posit.m_w = 1.0f; dFloat scale = 3.0f; height = dMax(height - 2.0f * radius / scale, dFloat(0.1f)); NewtonCollision* const bodyCapsule = NewtonCreateCapsule(world, radius / scale, radius / scale, height, 0, &shapeMatrix[0][0]); NewtonCollisionSetScale(bodyCapsule, 1.0f, scale, scale); // create the kinematic body NewtonBody* const body = NewtonCreateKinematicBody(world, bodyCapsule, &location[0][0]); // players must have weight, otherwise they are infinitely strong when they collide NewtonCollision* const shape = NewtonBodyGetCollision(body); NewtonBodySetMassProperties(body, mass, shape); // make the body collidable with other dynamics bodies, by default NewtonBodySetCollidable(body, 1); NewtonDestroyCollision(bodyCapsule); dCustomPlayerController& controller = m_playerList.Append()->GetInfo(); controller.m_localFrame = localAxis; controller.m_mass = mass; controller.m_invMass = 1.0f / mass; controller.m_manager = this; controller.m_kinematicBody = body; controller.m_contactPatch = radius / scale; controller.m_stepHeight = dMax (stepHeight, controller.m_contactPatch * 2.0f); return &controller; }
InstancedRendering::Batch* InstancedRendering::recordShape(ShapeType type, const SkRect& bounds, const SkMatrix& viewMatrix, GrColor color, const SkRect& localRect, bool antialias, const GrInstancedPipelineInfo& info, bool* useHWAA) { SkASSERT(State::kRecordingDraws == fState); if (info.fIsRenderingToFloat && !fCanRenderToFloat) { return nullptr; } AntialiasMode antialiasMode; if (!this->selectAntialiasMode(viewMatrix, antialias, info, useHWAA, &antialiasMode)) { return nullptr; } Batch* batch = this->createBatch(); batch->fInfo.fAntialiasMode = antialiasMode; batch->fInfo.fShapeTypes = GetShapeFlag(type); batch->fInfo.fCannotDiscard = !info.fCanDiscard; Instance& instance = batch->getSingleInstance(); instance.fInfo = (int)type << kShapeType_InfoBit; Batch::HasAABloat aaBloat = (antialiasMode == AntialiasMode::kCoverage) ? Batch::HasAABloat::kYes : Batch::HasAABloat::kNo; Batch::IsZeroArea zeroArea = (bounds.isEmpty()) ? Batch::IsZeroArea::kYes : Batch::IsZeroArea::kNo; // The instanced shape renderer draws rectangles of [-1, -1, +1, +1], so we find the matrix that // will map this rectangle to the same device coordinates as "viewMatrix * bounds". float sx = 0.5f * bounds.width(); float sy = 0.5f * bounds.height(); float tx = sx + bounds.fLeft; float ty = sy + bounds.fTop; if (!viewMatrix.hasPerspective()) { float* m = instance.fShapeMatrix2x3; m[0] = viewMatrix.getScaleX() * sx; m[1] = viewMatrix.getSkewX() * sy; m[2] = viewMatrix.getTranslateX() + viewMatrix.getScaleX() * tx + viewMatrix.getSkewX() * ty; m[3] = viewMatrix.getSkewY() * sx; m[4] = viewMatrix.getScaleY() * sy; m[5] = viewMatrix.getTranslateY() + viewMatrix.getSkewY() * tx + viewMatrix.getScaleY() * ty; // Since 'm' is a 2x3 matrix that maps the rect [-1, +1] into the shape's device-space quad, // it's quite simple to find the bounding rectangle: float devBoundsHalfWidth = fabsf(m[0]) + fabsf(m[1]); float devBoundsHalfHeight = fabsf(m[3]) + fabsf(m[4]); SkRect batchBounds; batchBounds.fLeft = m[2] - devBoundsHalfWidth; batchBounds.fRight = m[2] + devBoundsHalfWidth; batchBounds.fTop = m[5] - devBoundsHalfHeight; batchBounds.fBottom = m[5] + devBoundsHalfHeight; batch->setBounds(batchBounds, aaBloat, zeroArea); // TODO: Is this worth the CPU overhead? batch->fInfo.fNonSquare = fabsf(devBoundsHalfHeight - devBoundsHalfWidth) > 0.5f || // Early out. fabs(m[0] * m[3] + m[1] * m[4]) > 1e-3f || // Skew? fabs(m[0] * m[0] + m[1] * m[1] - m[3] * m[3] - m[4] * m[4]) > 1e-2f; // Diff. lengths? } else { SkMatrix shapeMatrix(viewMatrix); shapeMatrix.preTranslate(tx, ty); shapeMatrix.preScale(sx, sy); instance.fInfo |= kPerspective_InfoFlag; float* m = instance.fShapeMatrix2x3; m[0] = SkScalarToFloat(shapeMatrix.getScaleX()); m[1] = SkScalarToFloat(shapeMatrix.getSkewX()); m[2] = SkScalarToFloat(shapeMatrix.getTranslateX()); m[3] = SkScalarToFloat(shapeMatrix.getSkewY()); m[4] = SkScalarToFloat(shapeMatrix.getScaleY()); m[5] = SkScalarToFloat(shapeMatrix.getTranslateY()); // Send the perspective column as a param. batch->appendParamsTexel(shapeMatrix[SkMatrix::kMPersp0], shapeMatrix[SkMatrix::kMPersp1], shapeMatrix[SkMatrix::kMPersp2]); batch->fInfo.fHasPerspective = true; batch->setBounds(bounds, aaBloat, zeroArea); batch->fInfo.fNonSquare = true; } instance.fColor = color; const float* rectAsFloats = localRect.asScalars(); // Ensure SkScalar == float. memcpy(&instance.fLocalRect, rectAsFloats, 4 * sizeof(float)); batch->fPixelLoad = batch->bounds().height() * batch->bounds().width(); return batch; }
// -------------------------------------------------------------------------------------------- MStatus polyModifierCmd::connectNodes( MObject modifierNode ) // -------------------------------------------------------------------------------------------- // // Description: // // This method connects up the modifier nodes, while accounting for DG factors // such as construction history and tweaks. The method has a series of steps which // it runs through to process nodes under varying circumstances: // // 1) Gather meshNode connection data (ie. attributes and plugs) // // 2) Gather upstreamNode data - This is history-dependent. If the node has history, // an actual upstreamNode exists and that is used to // drive the input of our modifierNode. // // Otherwise, if the node ds not have history, the // meshNode is duplicated, set as an intermediate object // and regarded as our new upstreamNode which will drive // the input of our modifierNode. The case with history // already has this duplicate meshNode at the top, driving // all other history nodes and serving as a reference // to the "original state" of the node before any // modifications. // // 3) Gather modifierNode connection data // // 4) Process tweak data (if it exists) - This is history-dependent. If there is // history, the tweak data is extracted and deleted // from the meshNode and encapsulated inside a // polyTweak node. The polyTweak node is then // inserted ahead of the modifier node. // // If there is no history, the same is done as // in the history case, except the tweaks are // deleted from the duplicate meshNode in addition // to the actual meshNode. // // 5) Connect the nodes // // 6) Collapse/Bake nodes into the actual meshNode if the meshNode had no previous // construction history and construction history recording is turned off. // (ie. (!fHasHistory && !fHasRecordHistory) == true ) // { MStatus status; // Declare our internal processing data structure (see polyModifierCmd.h for definition) // modifyPolyData data; //->jetzt als ElementVariable // Get the mesh node, plugs and attributes // status = processMeshNode( data ); MCheckStatus( status, "processMeshNode" ); // Get upstream node, plugs and attributes // status = processUpstreamNode( data ); MCheckStatus( status, "processUpstreamNode" ); // Get the modifierNode attributes // status = processModifierNode( modifierNode, data ); MCheckStatus( status, "processModifierNode" ); // Process tweaks on the meshNode // status = processTweaks( data ); MCheckStatus( status, "processTweaks" ); if( fHasTweaks ) { status = fDGModifier.connect( data.upstreamNodeShape, data.upstreamNodeSrcAttr, data.tweakNode, data.tweakNodeDestAttr ); MCheckStatus( status, "upstream-tweak connect failed" ); status = fDGModifier.connect( data.tweakNode, data.tweakNodeSrcAttr, modifierNode, data.modifierNodeDestAttr ); MCheckStatus( status, "tweak-modifier connect failed" ); } else { //hier muessen die Plugs verwendet werden, weil die Attribute eventuell multis sind MPlug destPlug(modifierNode,data.modifierNodeDestAttr ); INVIS(cout<<data.upstreamNodeSrcPlug.name().asChar()<<" --> "<<destPlug.name().asChar()<<endl); status = fDGModifier.connect( data.upstreamNodeSrcPlug, destPlug ); MCheckStatus( status, "upstream-modifier connect failed" ); } // outMesh mit inputMesh verbinden // fDGModifier.connect(MPlug(modifierNode,data.modifierNodeSrcAttr), data.meshNodeDestPlug); // Ausserdem das MatrixAttribut des Meshes mit dem meshMatrix Attr der Node verbinden // MFnDependencyNode depFn( modifierNode ); MPlug meshMatrix( modifierNode, depFn.attribute("meshMatrix") ); depFn.setObject(data.meshNodeTransform); MPlug shapeMatrix( data.meshNodeTransform, depFn.attribute("worldMatrix") ); fDGModifier.connect(shapeMatrix.elementByLogicalIndex( 0 ), meshMatrix ); // Jetzt die ModifierNode mit der VisNode connecten /* status = fDGModifier.connect( modifierNode, data.modifierNodeSrcAttr, data.meshNodeShape, data.meshNodeDestAttr ); */ // MCheckStatus( status, "modifier-mesh connect failed" ); status = fDGModifier.doIt(); MCheckStatus( status, "modifier-mesh DOIT failed" ); if(createAnimCurves) { //AnimCurve erstellen(dies ist nur hier moeglich, da die Node erst nach dem DoIt wirklich existiert (scheinbar) MFnAnimCurve aCurve; MFnDependencyNode myDepNodeFn(modifierNode); aCurve.create(modifierNode,myDepNodeFn.attribute("csl"),MFnAnimCurve::kAnimCurveUU,&createSlideAnim,&status); } return status; }