Beispiel #1
0
        // slow, accessing verticesWithAttributes directly is faster
        public SpatialVectorDouble[] getVertexPositionsAsVector3Array()
        {
            var positionAccessor = verticesWithAttributes.double4PositionAccessor;

            SpatialVectorDouble[] result = new SpatialVectorDouble[verticesWithAttributes.numberOfVertices];
            for (int i = 0; i < verticesWithAttributes.numberOfVertices; i++)
            {
                result[i] = new SpatialVectorDouble(new double[] { positionAccessor[i][0], positionAccessor[i][1], positionAccessor[i][2], });
            }
            return(result);
        }
Beispiel #2
0
 public bool checkIntersectPosition(SpatialVectorDouble position)
 {
     for (int i = 0; i < k / 2; i++)
     {
         double dotOfBaseVectorWithPosition = SpatialVectorDouble.dot(baseVectors[i], position);
         if (min[i] > dotOfBaseVectorWithPosition || max[i] < dotOfBaseVectorWithPosition)
         {
             return(false);
         }
     }
     return(true);
 }
Beispiel #3
0
        public void command(HersheyInterpreter.EnumCommandType command, float x, float y)
        {
            SpatialVectorDouble currentPosition = new SpatialVectorDouble(new double[] { x, y }).componentMultiplication(scale) + center;

            if (command == HersheyInterpreter.EnumCommandType.MOVE)
            {
                lastPosition = currentPosition;
                return;
            }

            lineCommandInterpreter.drawLine((float)lastPosition.x, (float)lastPosition.y, (float)currentPosition.x, (float)currentPosition.y);
            lastPosition = currentPosition;
        }
Beispiel #4
0
        // \param dt the time diference of one simulation step, can be changed at runtime
        // \param targetDirection should be normalized
        // \param controller controller of the controlled entity
        public VehicleAlignToCommand(PhysicsEngine physicsEngine, double dt, SpatialVectorDouble targetDirection, EntityController controller, ulong controlledObjectId, double targetDerivationDistance, Pid.Configuration yawPidConfiguration, Pid.Configuration pitchPidConfiguration)
        {
            this.physicsEngine            = physicsEngine;
            this.dt                       = dt;
            this.controller               = controller;
            this.targetDirection          = targetDirection;
            this.controlledObjectId       = controlledObjectId;
            this.targetDerivationDistance = targetDerivationDistance;

            Trace.Assert(physicsEngine.existObjectById(controlledObjectId)); // object must exist hold by the physics engine

            yawPid   = Pid.makeByTargetAndConfiguration(0, yawPidConfiguration);
            pitchPid = Pid.makeByTargetAndConfiguration(0, pitchPidConfiguration);
        }
Beispiel #5
0
        // doesn't add the entity to the entity manager
        public Entity buildFromTemplate(GameObjectTemplate template, SpatialVectorDouble globalPosition, SpatialVectorDouble globalVelocity)
        {
            IList <IComponent> entityComponents = new List <IComponent>();



            PhysicsComponent physicsComponent = buildPhysicsComponentOfMainbody(template, globalPosition, globalVelocity);

            entityComponents.Add(physicsComponent);
            IList <ColliderComponent> colliderComponents = buildColliderComponents(template);

            // add physicsComponent with colliders to physics world
            physicsEngine.physicsAndMeshPairs.Add(new PhysicsComponentAndCollidersPair(physicsComponent, colliderComponents));

            // add solids
            SolidCluster solidCluster = buildSolidCluster(template);

            if (solidCluster.solids.Count > 0)
            {
                solidResponsibility.mapping.physicsObjectIdToSolidCluster[physicsComponent.id] = solidCluster;
            }

            // add effects
            IList <game.responsibilities.Effect> effects = buildEffects(template);

            if (effects.Count > 0)
            {
                effectResponsibility.physicsObjectIdToEffects[physicsComponent.id] = effects;
            }

            // add special attributes
            buildSpecialAttributes(template, entityComponents);

            // add thrusters and recalculate thruster angular rotation cache
            buildThrustersAndAddToObjectAndRecalcThrusterRelatedCache(template, physicsComponent);

            // add rendering mesh
            buildAndAddRenderingMesh(template, physicsComponent);



            // misc

            // PID controller configuration
            readPidControllerConfiguration(template, physicsComponent.id);



            return(Entity.make(entityComponents));
        }
Beispiel #6
0
        // helper
        static SpatialVectorDouble calcImpulse(SpatialVectorDouble relativeVelocity, double mass)
        {
            // e = 1/2 * m * v²
            double velocityMagnitude = relativeVelocity.length;

            if (velocityMagnitude < double.Epsilon)
            {
                return(new SpatialVectorDouble(new double[] { 0, 0, 0 }));
            }
            else
            {
                return(relativeVelocity.normalized().scale(0.5 * mass * velocityMagnitude * velocityMagnitude));
            }
        }
Beispiel #7
0
        // recalculates the convex hull based on the convex hull
        void recalcConvexHull()
        {
            boundingVolume.convexHull = new SpatialVectorDouble[boundingVolume.kdop.k];

            for (int baseVectorI = 0; baseVectorI < boundingVolume.kdop.baseVectors.Length; baseVectorI++)
            {
                SpatialVectorDouble baseVector = boundingVolume.kdop.baseVectors[baseVectorI];

                // the plane is the normal and w of the plane is the dot product of the point on the plane and the normal, which is the min/max value of the k-dop
                // the normal of the plane is the base vector of the k-dop for max and the negative normal for min

                boundingVolume.convexHull[baseVectorI] = new SpatialVectorDouble(new double[] { -baseVector[0], -baseVector[1], -baseVector[2], boundingVolume.kdop.min[baseVectorI] });
                boundingVolume.convexHull[boundingVolume.kdop.k / 2 + baseVectorI] = new SpatialVectorDouble(new double[] { baseVector[0], baseVector[1], baseVector[2], -boundingVolume.kdop.max[baseVectorI] });
            }
        }
Beispiel #8
0
        public static ClosedLoop generateStandardOutline(
            float insetWidth,
            float insetHeight,
            SpatialVectorDouble size
            )
        {
            ClosedLoop outline = new ClosedLoop();

            outline.points.Add(new SpatialVectorDouble(new double[] { 0.0f, 0.0f }));
            outline.points.Add(new SpatialVectorDouble(new double[] { size.x, 0.0f }));
            outline.points.Add(new SpatialVectorDouble(new double[] { size.x, size.y - insetHeight }));
            outline.points.Add(new SpatialVectorDouble(new double[] { size.x - insetWidth, size.y }));
            outline.points.Add(new SpatialVectorDouble(new double[] { 0.0f, size.y }));
            return(outline);
        }
Beispiel #9
0
        void moveAllPhysicsComponents(IEnumerable <PhysicsComponent> physicsComponents)
        {
            // NOTE PERFORMANCE< can't be parallelized because it is using one RungeKutta acceleration helper object
            //                   accesses and operations of it would overlap in parallel execution >
            foreach (PhysicsComponent iPhysicsComponent in physicsComponents)
            {
                // update acceleration for rungeKutta4.acceleration
                ((Acceleration)rungeKutta4.acceleration).accelerationForCurrentBody = iPhysicsComponent.linearAcceleration;

                SpatialVectorDouble oldPosition = iPhysicsComponent.position;

                rungeKutta4.integrate(ref iPhysicsComponent.rungeKutta4State, 0, (float)dt);
                iPhysicsComponent.updatePosition(iPhysicsComponent.position, oldPosition);
            }
        }
Beispiel #10
0
        private void renderEdge(SpatialVectorDouble vertex0, SpatialVectorDouble vertex1)
        {
            Matrix point0 = new Matrix(new double[] { vertex0.x, vertex0.y, vertex0.z, vertex0.w }, 1);
            Matrix point1 = new Matrix(new double[] { vertex1.x, vertex1.y, vertex1.z, vertex1.w }, 1);

            Matrix projectedPoint0 = modelViewProjection * point0;
            Matrix projectedPoint1 = modelViewProjection * point1;

            Matrix normalizedProjectedPoint0 = SoftwareRendererUtilities.project(projectedPoint0);
            Matrix normalizedProjectedPoint1 = SoftwareRendererUtilities.project(projectedPoint1);

            graphics.DrawLine(pen,
                              viewSize / 2 + (int)normalizedProjectedPoint0[0, 0], viewSize / 2 + (int)normalizedProjectedPoint0[1, 0],
                              viewSize / 2 + (int)normalizedProjectedPoint1[0, 0], viewSize / 2 + (int)normalizedProjectedPoint1[1, 0]);
        }
Beispiel #11
0
        public static KDop makeAabbKDopByCenterAndRadius(SpatialVectorDouble center, double radius)
        {
            Debug.Assert(radius > 0.0);

            KDop result = new KDop(KDop.BASEVECTORSOFKDOP6, 6, true);

            result.min[0] = center.x - radius;
            result.min[1] = center.y - radius;
            result.min[2] = center.z - radius;
            result.max[0] = center.x + radius;
            result.max[1] = center.y + radius;
            result.max[2] = center.z + radius;

            return(result);
        }
Beispiel #12
0
        public EnumNonPreemptiveTaskState process()
        {
            bool             objectExists;
            PhysicsComponent controlledObject = tryGetControlledObject(out objectExists);

            if (!objectExists)
            {
                return(EnumNonPreemptiveTaskState.FINISHEDSUCCESSFUL); // we finished if the object we have to align doesn't exist anymore
            }


            SpatialVectorDouble
                forwardVector = controlledObject.forwardVector,
                upVector      = controlledObject.upVector,
                sideVector    = controlledObject.sideVector;

            double
                dotOfUpVectorAndTargetDirection      = SpatialVectorDouble.dot(upVector, targetDirection),
                dotOfSideVectorAndTargetDirection    = SpatialVectorDouble.dot(sideVector, targetDirection),
                dotOfForwardVectorAndTargetDirection = SpatialVectorDouble.dot(forwardVector, targetDirection);

            //if (processingBegun) {
            //pitchPid.reset(dotOfUpVectorAndTargetDirection);
            //yawPid.reset(dotOfSideVectorAndTargetDirection);
            //}
            //processingBegun = false;


            // the dot product results are like our rotation delta of the different axis
            // now we need to put these into our PID's for the different axis to get the control value(s)

            double currentPitchDerivative, currentYawDerivative;
            double pitchControl = pitchPid.step(dotOfUpVectorAndTargetDirection, dt, out currentPitchDerivative);
            double yawControl   = yawPid.step(dotOfSideVectorAndTargetDirection, dt, out currentYawDerivative);


            // send it to the controller
            controller.inputPitch = (float)pitchControl;
            controller.inputYaw   = (float)yawControl;

            // check for termination criterium of this Command
            if (Math.dist2FromZero(currentPitchDerivative, currentYawDerivative) < targetDerivationDistance)
            {
                return(EnumNonPreemptiveTaskState.FINISHEDSUCCESSFUL);
            }
            return(EnumNonPreemptiveTaskState.INPROGRESS);
        }
Beispiel #13
0
        void calcForcesForRigidBodies()
        {
            // TODO PERFORMANCE< parallel for >
            foreach (PhysicsComponent iPhysicsComponent in physicsAndMeshPairs.Select(v => v.physicsComponent))
            {
                // see https://github.com/PtrMan/SpaceSimCore/blob/master/src/physics/PhysicsEngine.cpp#L87

                iPhysicsComponent.eulerAngularAcceleration = new SpatialVectorDouble(new double[] { 0, 0, 0 });

                foreach (AttachedForce iterationAttachedForce in iPhysicsComponent.attachedForces)
                {
                    SpatialVectorDouble localForce = iterationAttachedForce.forceVectorInNewton;

                    applyForceToLinearAndAngularVelocity(iPhysicsComponent, localForce, iterationAttachedForce.objectLocalPosition);
                }
            }
        }
Beispiel #14
0
        public static KDop calculateKdopFromVerticesAndbaseVectors(IList <SpatialVectorDouble> vertices, SpatialVectorDouble[] baseVectors, bool baseVectorsStartWithAabb)
        {
            uint k = (uint)baseVectors.Length * 2;

            KDop result = new KDop(baseVectors, k, baseVectorsStartWithAabb);

            foreach (SpatialVectorDouble iterationVertex in vertices)
            {
                for (int baseVectorI = 0; baseVectorI < baseVectors.Length; baseVectorI++)
                {
                    double dotWithIterationVector = SpatialVectorDouble.dot(iterationVertex, baseVectors[baseVectorI]);
                    result.min[baseVectorI] = System.Math.Min(result.min[baseVectorI], dotWithIterationVector);
                    result.max[baseVectorI] = System.Math.Max(result.max[baseVectorI], dotWithIterationVector);
                }
            }

            return(result);
        }
Beispiel #15
0
        public void integrate(ref RungeKutta4State state, float t, float dt)
        {
            Derivative a, b, c, d, dummy;

            dummy.dx = new SpatialVectorDouble(new double[] { 0.0, 0.0, 0.0 });
            dummy.dv = new SpatialVectorDouble(new double[] { 0.0, 0.0, 0.0 });

            a = evaluate(ref state, t, 0.0f, ref dummy);
            b = evaluate(ref state, t, dt * 0.5f, ref a);
            c = evaluate(ref state, t, dt * 0.5f, ref b);
            d = evaluate(ref state, t, dt, ref c);

            SpatialVectorDouble dxdt = (a.dx + (b.dx + c.dx).scale(2.0f) + d.dx).scale(1.0f / 6.0f);
            SpatialVectorDouble dvdt = (a.dv + (b.dv + c.dv).scale(2.0f) + d.dv).scale(1.0f / 6.0f);

            state.x = state.x + dxdt.scale(dt);
            state.v = state.v + dvdt.scale(dt);
        }
Beispiel #16
0
        // useful for acceleration with radiation or a shockwave
        public static void accelerateByRadialPressure(SpatialVectorDouble energySourcePosition, double energyInJoules, IList <FracturedParticle> particles)
        {
            foreach (FracturedParticle iParticle in particles)
            {
                SpatialVectorDouble diff = iParticle.relativePosition - energySourcePosition;
                double distance          = diff.length;

                if (distance > 0.0)
                {
                    double surfaceAreaOfRadiationSphereAtDistance = Area.ofSphere(distance);

                    double surfaceAreaOfProjectedSphere = ProjectedArea.ofSphere(iParticle.radius);

                    double absorbedEnergyRatio    = System.Math.Min(surfaceAreaOfProjectedSphere / surfaceAreaOfRadiationSphereAtDistance, 1.0);
                    double absolvedEnergyInJoules = absorbedEnergyRatio * energyInJoules;
                    iParticle.accelerateByEnergyInJoules(diff.normalized(), absolvedEnergyInJoules);
                }
            }
        }
Beispiel #17
0
        public static SpatialVectorDouble calcPlaneByFace(MeshWithExplicitFaces.Face face, SpatialVectorDouble[] vertices, int normalSideness = 1)
        {
            SpatialVectorDouble p0 = vertices[face.verticesIndices[0]];
            SpatialVectorDouble p1 = vertices[face.verticesIndices[1]];
            SpatialVectorDouble p2 = vertices[face.verticesIndices[2]];

            SpatialVectorDouble diff01 = p1 - p0;
            SpatialVectorDouble diff02 = p2 - p0;
            SpatialVectorDouble normal = SpatialVectorDouble.crossProduct(diff01, diff02).normalized();


            if (normalSideness == -1)
            {
                normal = new SpatialVectorDouble(new double[] { -normal.x, -normal.y, -normal.z });
            }

            double w = -Plane.calcW(p0, normal);

            return(new SpatialVectorDouble(new double[] { normal.x, normal.y, normal.z, w })); // plane is normal,w
        }
Beispiel #18
0
        // tests if a sphere is inside the frustum
        public EnumFrustumIntersectionResult calcContainsForSphere(FrustumSphere sphere)
        {
            for (int i = 0; i < planes.Length; i++)
            {
                // find the distance to this plane
                double distance = SpatialVectorDouble.dot(planes[i].normal, sphere.position) + planes[i].distance;

                if (distance < -sphere.radius)
                {
                    return(EnumFrustumIntersectionResult.OUTSIDE);
                }

                if (System.Math.Abs(distance) < sphere.radius)
                {
                    return(EnumFrustumIntersectionResult.INTERSECT);
                }
            }

            return(EnumFrustumIntersectionResult.INSIDE);
        }
Beispiel #19
0
        IList <FracturedParticle> fractureSolidWithPositionAndRotation(SpatialVectorDouble objectGlobalPosition, Quaternion objectRotation, SolidCluster.SolidWithPositionAndRotation solidWithPositionAndRotation)
        {
            uint roughtlyNumberOfFracturedElements = 64;

            IList <FracturedParticle> fracturedParticles = SimpleFracturing.fractureSolid(solidWithPositionAndRotation.solid, roughtlyNumberOfFracturedElements);

            // transform positions from local to global
            foreach (FracturedParticle iFracturedParticle in fracturedParticles)
            {
                Matrix localToGlobalTranslation = MatrixUtilities.calcLocalToGlobalTranslationMatrix(objectGlobalPosition);
                Matrix localToGlobalRotation    = QuaternionUtilities.convToRotationMatrix4(objectRotation);

                Matrix localToGlobal =
                    (localToGlobalTranslation * localToGlobalRotation) *
                    MatrixUtilities.calcLocalToGlobalRotationAndTranslationMatrix(solidWithPositionAndRotation.localPosition, solidWithPositionAndRotation.localRotation);

                iFracturedParticle.relativePosition = SpatialVectorUtilities.toVector3(new SpatialVectorDouble(localToGlobal * SpatialVectorUtilities.toVector4(iFracturedParticle.relativePosition).asMatrix));
            }

            return(fracturedParticles);
        }
        // generalized way to rotate in a specific direction
        public void controlSolve(PhysicsComponent @object, float roll, float pitch, float yaw)
        {
            IList <ThrusterResponsibility.ThrusterBinding> thrusterBindings;

            if (!thrusterResponsibility.physicsObjectIdToThrusters.TryGetValue(@object.id, out thrusterBindings))
            {
                return;
            }

            SpatialVectorDouble rotationTargetVector = new SpatialVectorDouble(new double[] { roll, yaw, pitch }); // vulkan coordinate system rotation

            double maximalAngularAccelerationMagnitude = 0.0;

            foreach (var iThrusterBinding in thrusterBindings)
            {
                maximalAngularAccelerationMagnitude = System.Math.Max(maximalAngularAccelerationMagnitude, iThrusterBinding.additionalInformation.cachedAngularAccelerationOnObject.length);
            }


            foreach (var iThrusterBinding in thrusterBindings)
            {
                SpatialVectorDouble normalizedAngularAccelerationOnObject;
                if (iThrusterBinding.additionalInformation.cachedAngularAccelerationOnObject.length < double.Epsilon)
                {
                    normalizedAngularAccelerationOnObject = new SpatialVectorDouble(new double[] { 0, 0, 0 });
                }
                else
                {
                    SpatialVectorDouble cachedAngularAccelerationOnObject = iThrusterBinding.additionalInformation.cachedAngularAccelerationOnObject;
                    double normalizedMangitude = cachedAngularAccelerationOnObject.length / maximalAngularAccelerationMagnitude;
                    normalizedAngularAccelerationOnObject = cachedAngularAccelerationOnObject.normalized().scale(normalizedMangitude);
                }

                // calculate the relative thrust by the dot product because we want to rotate the best way in the wished rotation acceleration (given by roll, pitch, yaw)
                double relativeThrust = SpatialVectorDouble.dot(normalizedAngularAccelerationOnObject, rotationTargetVector);
                relativeThrust = System.Math.Max(relativeThrust, 0); // thruster can only thrust positivly

                iThrusterBinding.relative += (float)relativeThrust;  // now we add to not cancel away the effects of the other thrusters
            }
        }
Beispiel #21
0
        // calculates the gravitational forces and coresponding accelerations
        public void calcForcesAndAccelerationsForPhysicsComponents(IEnumerable <PhysicsComponent> physicsComponents)
        {
            foreach (PhysicsComponent iPhysicsComponent in physicsComponents)
            {
                SpatialVectorDouble sumOfForce = new SpatialVectorDouble(new double[] { 0, 0, 0 });

                foreach (CelestialObjectWithPosition iCelestialObject in celestialObjects)
                {
                    SpatialVectorDouble extrapolatedPosition = iPhysicsComponent.rungeKutta4State.x + iPhysicsComponent.rungeKutta4State.v.scale(PhysicsEngine.dt);
                    SpatialVectorDouble difference           = iCelestialObject.position - extrapolatedPosition;
                    SpatialVectorDouble direction            = difference.normalized();
                    double distanceSquared = difference.lengthSquared;

                    double forceMagnitude = Orbit.calculateForceBetweenObjectsByDistance(iPhysicsComponent.mass, iCelestialObject.celestialObject.mass, distanceSquared);

                    sumOfForce += direction.scale(forceMagnitude);
                }

                SpatialVectorDouble acceleration = sumOfForce.scale(iPhysicsComponent.invMass);
                iPhysicsComponent.linearAcceleration += acceleration;
            }
        }
Beispiel #22
0
        // inertia tensor can be null for particles which don't rotate
        internal PhysicsComponent(SpatialVectorDouble position, SpatialVectorDouble velocity, double mass, Matrix?inertiaTensor, ulong id)
        {
            Trace.Assert(position.height == 3 && velocity.height == 3);


            this.privateId = id;

            this.mass                 = mass;
            this.position             = position;
            this.internalLastPosition = position; // TODO< minus last time step velocity ? >
            this.velocity             = velocity;

            rotation = QuaternionUtilities.makeIdentity();
            eulerLocalAngularVelocity = new SpatialVectorDouble(new double[] { 0, 0, 0 });

            if (inertiaTensor != null)
            {
                Trace.Assert(inertiaTensor.Value.height == 3 && inertiaTensor.Value.width == 3);
                this.internalInertiaTensor = new ChangeCallbackCalculateInverse();
                this.internalInertiaTensor.set(inertiaTensor.Value);
            }
        }
Beispiel #23
0
        public void draw(GuiElementDrawCommandHandle handle, SpatialVectorDouble position)
        {
            if (graphics == null)
            {
                return;
            }

            if (handle.id == 0xdeadf00d)    // pseudo special handle to ignore rendering
            {
                return;
            }

            GuiElementDrawCommand drawCommand = guiElementDrawCommands.drawCommandsById[handle.id];

            if (drawCommand.type == GuiElementDrawCommand.EnumType.CLOSEDLOOPGEOMETRY)
            {
                Point[] points = new Point[drawCommand.closedLoopGeometry.Count + 1];
                for (int i = 0; i < drawCommand.closedLoopGeometry.Count; i++)
                {
                    // TODO< pull size of screen from context >
                    points[i] = new Point((int)((drawCommand.closedLoopGeometry[i].x + position.x) * 150.0f), (int)((drawCommand.closedLoopGeometry[i].y + position.y) * 150.0f));
                }
                points[points.Length - 1] = new Point((int)((drawCommand.closedLoopGeometry[0].x + position.x) * 150.0f), (int)((drawCommand.closedLoopGeometry[0].y + position.y) * 150.0f));

                graphics.DrawLines(new Pen(Brushes.Black), points);
            }
            else if (drawCommand.type == GuiElementDrawCommand.EnumType.LINES)
            {
                foreach (var iLine in drawCommand.lines)
                {
                    graphics.DrawLine(
                        new Pen(Brushes.Black),
                        (int)((iLine.a.x + position.x) * 150.0f), (int)((iLine.a.y + position.y) * 150.0f),
                        (int)((iLine.b.x + position.x) * 150.0f), (int)((iLine.b.y + position.y) * 150.0f)
                        );
                }
            }
        }
Beispiel #24
0
        public void renderString(string @string, SpatialVectorDouble signScale, SpatialVectorDouble position)
        {
            Debug.Assert(lineRendererDriver != null);

            SpatialVectorDouble currentPosition = position.deepClone();



            // TODO< find optimal scale >
            const float rescalingFactor = 1.0f / 16.0f;

            lineRendererDriver.scale = signScale.scale(rescalingFactor); // normalize scale with scale of a typical sign

            int i = 0;

            foreach (char @char in @string)
            {
                lineRendererDriver.center = currentPosition;

                // continue with next sign if we can't look it up
                if (!signToHersheyCommandIndex.ContainsKey(@char))
                {
                    continue;
                }

                int    commandIndex    = signToHersheyCommandIndex[@char];// (60+30-1) + 3*30; // signToHersheyCommandIndex[@char];
                string hersheyCommands = hersheyCommandsOfLetters[commandIndex];

                hesheyInterpreter.interpret(hersheyCommands, lineRendererDriver);

                float widthBeforeRescaling = lineRendererDriver.positionRight - lineRendererDriver.positionLeft; // width is the difference
                float width = (widthBeforeRescaling * rescalingFactor) * (float)signScale.x;

                currentPosition.x += width;

                i++;// for testing
            }
        }
Beispiel #25
0
        public void tick(
            SpatialVectorDouble mousePosition,
            MouseStateTracker.EnumMouseButtonState mouseButtonState
            )
        {
            IEnumerable <GuiElement> elementsWhichOverlapMousePosition =
                mousePositionChecker.getElementsWhichOverlapTheMousePosition(mousePosition);

            if (mouseButtonState == MouseStateTracker.EnumMouseButtonState.WASDOWN)
            {
                // update selection
                selectionInteraction.eventMouseReleased(mousePosition);

                // mousebutton was released, send message to all elements below the current mouse position

                foreach (GuiElement iElement in elementsWhichOverlapMousePosition)
                {
                    if (iElement is IReactingToMouse)
                    {
                        ((IReactingToMouse)iElement).reactingToMouse.wasClicked(mousePosition);
                    }
                }
            }
        }
Beispiel #26
0
        private void renderMesh(TransformedMeshComponent transformedMeshComponent)
        {
            foreach (MeshWithExplicitFaces.Face iterationFace in transformedMeshComponent.meshComponent.mesh.faces)
            {
                for (int edgeI = 0; edgeI < iterationFace.verticesIndices.Length - 1; edgeI++)
                {
                    int vertexIndex0 = (int)iterationFace.verticesIndices[edgeI];
                    int vertexIndex1 = (int)iterationFace.verticesIndices[edgeI + 1];

                    SpatialVectorDouble vertex0 = translateTo4ComponentVector(transformedMeshComponent.transformedVertices[vertexIndex0]);
                    SpatialVectorDouble vertex1 = translateTo4ComponentVector(transformedMeshComponent.transformedVertices[vertexIndex1]);
                    renderEdge(vertex0, vertex1);
                }

                {
                    int vertexIndex0 = (int)iterationFace.verticesIndices[iterationFace.verticesIndices.Length - 1];
                    int vertexIndex1 = (int)iterationFace.verticesIndices[0];

                    SpatialVectorDouble vertex0 = translateTo4ComponentVector(transformedMeshComponent.transformedVertices[vertexIndex0]);
                    SpatialVectorDouble vertex1 = translateTo4ComponentVector(transformedMeshComponent.transformedVertices[vertexIndex1]);
                    renderEdge(vertex0, vertex1);
                }
            }
        }
Beispiel #27
0
        // called from outside when the mouse button was released
        public void eventMouseReleased(SpatialVectorDouble mousePosition)
        {
            IEnumerable <GuiElement> guiElementsUnderMousePositionAsEnumerable =
                positionChecker.getElementsWhichOverlapTheMousePosition(mousePosition);
            IList <GuiElement> guiElementsUnderMousePosition = new List <GuiElement>(guiElementsUnderMousePositionAsEnumerable);

            if (guiElementsUnderMousePosition.Count > 0)
            {
                // change the selection

                // we just take first GuiElement in case of multiple
                // NOTE< could be a problem if there are multiple elements under the mouse position, we let it this way for now >
                GuiElement elementUnderMousePosition = guiElementsUnderMousePosition[0];

                // delesection
                trySendDeselectionToElementIfNotSameElement(elementUnderMousePosition);

                // selection
                if (!isSameAsAlreadySelectedElement(elementUnderMousePosition))
                {
                    changeSelectionTo(elementUnderMousePosition);
                }
            }
        }
Beispiel #28
0
        static void applyForceToLinearAndAngularVelocity(PhysicsComponent physicsComponent, SpatialVectorDouble localForce, SpatialVectorDouble objectLocalPositionOfForce)
        {
            { // linear part
              // to calculate the linear component we use the dot product
                double scaleOfLinearForce = 0.0;
                if (localForce.length > double.Epsilon)
                {
                    double dotOfForceAndLocalPosition = SpatialVectorDouble.dot(localForce.normalized(), objectLocalPositionOfForce.normalized());
                    scaleOfLinearForce = System.Math.Abs(dotOfForceAndLocalPosition);
                }

                // the linear force (and resulting acceleration) is the force scaled by the dot product

                Matrix rotationMatrix           = physicsComponent.calcLocalToGlobalRotationMatrix();
                Matrix globalForceAsMatrix      = rotationMatrix * SpatialVectorUtilities.toVector4(localForce).asMatrix;
                SpatialVectorDouble globalForce = SpatialVectorUtilities.toVector3(new SpatialVectorDouble(globalForceAsMatrix));

                physicsComponent.linearAcceleration += globalForce.scale(scaleOfLinearForce * physicsComponent.invMass);
            }

            { // angular part
                physicsComponent.eulerAngularAcceleration += physicsComponent.calcAngularAccelerationOfRigidBodyForAppliedForce(objectLocalPositionOfForce, localForce);
            }
        }
Beispiel #29
0
        static IList <ColliderComponent> buildColliderComponents(GameObjectTemplate template)
        {
            IList <ColliderComponent> colliderComponents = new List <ColliderComponent>();

            foreach (Collider iCollider in template.colliders)
            {
                SpatialVectorDouble colliderComponentSize          = new SpatialVectorDouble(iCollider.size);
                SpatialVectorDouble colliderComponentLocalPosition = new SpatialVectorDouble(iCollider.localPosition);
                SpatialVectorDouble colliderComponentLocalRotation = new SpatialVectorDouble(iCollider.localRotation);

                ColliderComponent colliderComponent;
                if (template.mainMassShapeType == "box")
                {
                    colliderComponent = ColliderComponent.makeBox(colliderComponentSize, colliderComponentLocalPosition, colliderComponentLocalRotation);
                }
                else
                {
                    throw new Exception("Invalid collider shapeType " + iCollider.shapeType);
                }
                colliderComponents.Add(colliderComponent);
            }

            return(colliderComponents);
        }
Beispiel #30
0
 private Solid(EnumShapeType shapeType, Composition composition, SpatialVectorDouble size)
 {
     this.privateShapeType = shapeType;
     this.size             = size;
     this.composition      = composition;
 }